Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

📰 Painless universal pre-rendering for Webpack.

License

NotificationsYou must be signed in to change notification settings

curology/prerender-loader

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

prerender-loader

prerender-loadernpm

Painless universal prerendering for Webpack. Works great withhtml-webpack-plugin.

🧐What is Prerendering?

Pre-rendering describes the process of rendering a client-side application atbuild time, producing useful static HTML that can be sent to the browserinstead of an empty bootstrapping page.

Pre-rendering is like Server-Side Rendering, just done at build time to producestatic files. Both techniques help get meaningful content onto the user'sscreen faster.

Features

  • Works entirely within Webpack
  • Integrates withhtml-webpack-plugin
  • Works withwebpack-dev-server /webpack serve
  • Supports both DOM and String prerendering
  • Asynchronous rendering via async/await or Promises

How does it work?

prerender-loader renders your web application within Webpack during builds,producing static HTML. When the loader is applied to an HTML file, it creates aDOM structure from that HTML, compiles the application, runs it within the DOMand serializes the result back to HTML.


Installation

First, installprerender-loader as a development dependency:

npm i -D prerender-loader

Usage

In most cases, you'll want to apply the loader to yourhtml-webpack-plugintemplate option:

// webpack.config.jsmodule.exports = {  plugins: [    new HtmlWebpackPlugin({-     template: 'index.html',+     template: '!!prerender-loader?string!index.html',      // any other options you'd normally set are still supported:      compile: false,      inject: true    })  ]}

What does all that punctuation mean? Let's break the whole loader stringdown:

In Webpack, a module identifier beginning with!! will bypass any configuredloaders frommodule.rules - here we're saying "don't do anything toindex.html except what I've defined here

The?string parameter tellsprerender-loader to output an ES moduleexporting the prerendered HTML string, rather than returning the HTML directly.

Finally, everything up to the last! in a module identifier is the inlineloader definition (the transforms to apply to a given module). The filename ofthe module to load comes after the!.

Note: If you've already set uphtml-loader orraw-loader to handle.html files, you can skip both options and simply pass atemplate value of"prerender-loader!index.html"!

As with any loader, it is also possible to applyprerender-loader on-the-fly:

consthtml=require('prerender-loader?!./app.html');

... or in your Webpack configuration'smodule.rules section:

module.exports={module:{rules:[{test:'src/index.html',loader:'prerender-loader?string'}]}}

Once you haveprerender-loader in-place, prerendering is now turned on. Duringyour build, the app will be executed, with any modifications it makes toindex.html will be saved to disk. This is fine for the needs of many apps,but you can also take more explicit control over your prerendering: either usingthe DOM or by rendering to a String.

DOM Prerendering

During prerendering, your application gets compiled and run directly underNodeJS, but within aJSDOM container so that you can use the familiar browserglobals likedocument andwindow.

Here's an exampleentry module that uses DOM prerendering:

import{render}from'fancy-dom-library';importAppfrom'./app';exportdefault()=>{render(<App/>,document.body);};

In all cases, asynchronous functions and callbacks are supported:

import{mount}from'other-fancy-library';importappfrom'./app';exportdefaultasyncfunctionprerender(){letres=awaitfetch('https://example.com');letdata=awaitres.json();mount(app(data),document.getElementById('app'));}

String Prerendering

It's also possible to export a function from your Webpack entry module, whichgives you full control over prerendering:prerender-loader will call thefunction and its return value will be used as the static HTML. If the exportedfunction returns a Promise, it will be awaited and the resolved value will beused.

import{renderToString}from'react-dom';importAppfrom'./app';exportdefault()=>{consthtml=renderToString(<App/>);// returned HTML will be injected into <body>:returnhtml;};

In addition to DOM and String prerendering, it's also possible to use acombination of the two. If an application's Webpack entry exports a prerenderfunction that doesn't return a value, the default DOM serialization will kickin, just like in DOM prerendering. This means you can use your exportedprerender function to trigger DOM manipulation ("client-side" rendering), andthen just letprerender-loader handle generating the static HTML for whatevergot rendered.

Here's an example that renders aPreact application and waits for DOMrendering to settle down before allowing prerender-loader to serialize thedocument to static HTML:

import{h,options}from'preact';import{renderToString}from'preact';importAppfrom'./app';// we're done when there are no renders for 50ms:constIDLE_TIMEOUT=50;exportdefault()=>newPromise(resolve=>{lettimer;// each time preact re-renders, reset our idle timer:options.debounceRendering=commit=>{clearTimeout(timer);timer=setTimeout(resolve,IDLE_TIMEOUT);commit();};// render into <body> using normal client-side rendering:render(<App/>,document.body);});

Injecting content into the HTML

When applied to a.html file,prerender-loader will inject prerenderedcontent at the end of<body> by default. If you want to place the contentsomewhere else, you can add a{{prerender}} field:

<html><body><divid="app_root"><!-- Inject any pre-rendered HTML here: -->      {{prerender}}</div></body></html>

This works well if you intend to provide a prerender function that only returnsyour application's HTML structure, not the full document's HTML.

Prerendering JavaScript Files

In addition to processing.html files, the loader can also directly pre-render.js scripts. The only difference is that the DOM used for prerender will beinitially empty:

constprerenderedHtml=require('!prerender-loader?string!./app.js');

Options

All options are ... optional.

OptionTypeDefaultDescription
stringbooleanfalseOutput a JS module exporting an HTML String instead of the HTML itself
disabledbooleanfalseBypass the loader entirely (but still respectoptions.string)
documentUrlstring'http://localhost'Change the jsdom's URL (affectswindow.location,document.URL...)
paramsobjectnullOptions to pass to your prerender function
envobject{}Environment variables to define when building JS for prerendering

License

Apache 2.0

This is not an official Google product.

About

📰 Painless universal pre-rendering for Webpack.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript100.0%

[8]ページ先頭

©2009-2025 Movatter.jp