1.0.1 • Published 6 years ago

webpack-side-rendering-plugin v1.0.1

Weekly downloads
2
License
BSD-2-Clause
Repository
github
Last release
6 years ago

WebPack Side Rendering Plugin

License Build Status

Install

$ yarn add -D webpack
$ yarn add -D webpack-side-rendering-plugin

Usage

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 config

index.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'
    })
  ]
}
1.0.1

6 years ago

1.0.0

6 years ago