diff --git a/README.md b/README.md index ad10100e..2b7ebcbf 100644 --- a/README.md +++ b/README.md @@ -491,6 +491,51 @@ module.exports = { } ``` +### Server-side rendering + +To create a webpack build of [isomorphic](https://www.lullabot.com/articles/what-is-an-isomorphic-application)/[universal](http://www.acuriousanimal.com/2016/08/10/universal-applications.html) web application that pre-renders pages on the server side you might need to bundle CSS dependencies, such as `bootstrap.min.css`, installed from `node_modules`. + +There are several caveats in loading CSS in server-side environment: + +1) `style-loader` [can't be used in server-side node.js](https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/503), because it refers to `window` global when trying to inline your `css` into the javascript bundle. You need to use [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) with `css-loader` to extract styles into a separate file. +2) [target: node](https://webpack.js.org/concepts/targets/#usage) setting and [webpack-node-externals](https://github.com/liady/webpack-node-externals) package should be used to keep standard node.js modules and javascript dependencies from `node_modules` outside of the bundle. +3) with default `webpack-node-externals` setup, CSS that resides in `node_modules` will also be excluded from the bundle. Imports of CSS files in sources will be replaced with `require('bootstrap.min.css')` statements in the bundle as if they were javascript, which results in `SyntaxError` in runtime. Thus non-javascript dependencies in `node_modules` need to be [whitelisted from externals](https://github.com/liady/webpack-node-externals#how-can-i-bundle-required-assets-ie-css-files-from-node_modules). + +**webpack.config.js** +```js +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const nodeExternals = require('webpack-node-externals'); + +module.exports = { + target: 'node', // don't bundle standard node.js modules such as http or path + externals: [nodeExternals({ // don't bundle dependencies from node_modules folder, except by non-javascript files + whitelist: [ // non-javascript files in node_modules should go to the bundle and be processed by ExtractTextPlugin + /\.(?!(?:jsx?|json)$).{1,5}$/i, + ], + })], + plugins: [ + new ExtractTextPlugin('server.css') // extract css files into server.css bundle + ], + ... + module: { + rules: [ + ... + { + test: /\.css$/, + use: ExtractTextPlugin.extract({ + use: [ + { loader: 'css-loader', options: {sourceMap: true} } + ] + }) + }, + ... + ] + } +}; +``` + + +

Maintainers