1.0.1 • Published 8 years ago
webpack-side-rendering-plugin v1.0.1
WebPack Side Rendering Plugin
Install
$ yarn add -D webpack
$ yarn add -D webpack-side-rendering-pluginUsage
webpack.config
import WebpackSideRendering from 'webpack-side-rendering-plugin'
const config = {
entry: './index.js',
output: {
filename: 'index.js',
path: 'dist',
libraryTarget: 'umd2'
},
plugins: [
new WebpackSideRendering({
paths: [
'/hello/',
'/world/'
],
})
]
};
export default configindex.js
Sync rendering:
export default (options) => {
return '<html>' + options.path + '</html>';
};Async rendering via promises:
export default (options) => {
return Promise.resolve('<html>' + options.path + '</html>');
};Multi rendering
If you need to generate multiple files per render, or you need to alter the path, you can return an object instead of a string, where each key is the path, and the value is the file contents:
export default (options) => {
return {
'/': '<html>Home</html>',
'/hello': '<html>Hello</html>',
'/world': '<html>World</html>'
};
};Note that this will still be executed for each entry in your paths array in your plugin config.
Default options
export interface IRenderingOptions {
// list of the available assets
// IAssetsIndex is a hash of IAsset
assets: bc.IAssetsIndex
// The path currently being rendered:
path: string
// the public prefix mean the same thing as webpack.output.publicPath but this value is local to this instance
publicPrefix: string
}
export interface IAsset {
chunkname: string
filename: string
// supplemental asset attribute exported with exportAttrs
[name: string]: any
}Any additional locals provided in your config are also available.
Custom file names
By providing paths that end in .html, you can generate custom file names other than the default index.html. Please note that this may break compatibility with your router, if you're using one.
module.exports = {
...
plugins: [
new WebpackSideRendering({
paths: [
'/index.html',
'/news.html',
'/about.html'
]
})
]
};React + Redux with multiple JS assets (commonChunks / vendor / manifest) support
react.jsx
function bootstap() {
return (
<App />
)
}
if (!window.hasOwnProperty('_runScripts')) {
React.render( bootstrap(), global.document.getElementById('reactroot') );
}
export default (data) => {
const assets = Object.values(options.assets)
const js = assets.filter(asset => asset.filename.match(/\.js$/)).map(asset => ('<script src="'+asset.filename+'"></script>')).join('')
const html = ReactDOMServer.renderToString(bootstrap())
const preloadedState = JSON.stringify(reduxStore.getState()).replace(/</g, '\\u003c')
return (
`<!DOCTYPE html>
<html><head>
<meta charset="utf8">
<script>window.__PRELOADED_STATE__ = ${preloadedState};</script>
</head><body>
<div id="reactroot">${html}</div>
${js}
</body></html>`
)
}Specifying entry
This plugin defaults to the first chunk found. While this should work in most cases, you can specify the entry name if needed:
module.exports = {
...,
plugins: [
new WebpackSideRendering({
entry: 'main'
})
]
}