How to create a server bundle with Webpack for universal rendering

The recipe for setting up a universal rendering in the official Redux docs are good but it lacks one thing: It doesn’t describe how to use Webpack for creating a bundle of the server side code. There are boilerplate projects that does it, but they usually do a million other things as well so it’s complex to understand how it works.

Follow this step by step tutorial and learn how to use Webpack 2 to create a bundle of your server code.

I have created a Github repository with a fully working implementation from this tutorial. I suggest to git clone it and run it locally while reading this post. If you found it valuable I appreciate if you star it in Github 🙂

1. Create Webpack server config

Open up your webpack.config.js  and duplicate your existing client config and name it server. We are going to keep both the client and the server config in the file webpack.config.js .

Before:

const client = {
  // Existing webpack config
}
module.exports = client;

After:

const client = {
  // Existing webpack config
}

const server = {
  // Existing webpack config
}
module.exports = [client, server];

 2. Go through your new Webpack server config

  • Configure the entry section. Set the file name of the server code, for example server.js
  • Configure the output section. Set the filename and path.
  • Go through all plugins in the plugins section. Which ones makes sense on the backend? You can remove plugins used for code splitting, uglifyjs, etc.

3. Add node as target

We must tell Webpack that we are bundling node code by setting target to node.

const server = {
  ..
  target: "node",
  ..
}

4. Ignore node_modules

We are going to use webpack-node-externals, to ignores files in node_modules  folder. First, install it.

npm install --save-dev webpack-node-externals

Import it by adding this to the top of your webpack.config.js  file:

const nodeExternals = require('webpack-node-externals');

Then add it to your server config.

const server = {
  ..
  externals: [nodeExternals()],
  ..
}

4. Configure source maps (optional)

If you followed all steps up to this point, you should now have a fully working Webpack config for your server code. Try it and make sure it works before moving on!

This step is optional, but I recommend to set this up for production use.

The reason we want source maps is that we want stack traces to show file names and line number from our original files, not our generated bundle.

First, we need to tell Webpack to generate the source maps:

const server = {
  ..
  devtool: "source-map",
  ..
}

Then we need to use the source maps in our bundle. Install source-map-support

npm install --save-dev source-map-support

And then add this to the plugin section of your newly created server config:

const server = {
  ..
  plugins: [
    ..
    new webpack.BannerPlugin({ 
      banner: 'require("source-map-support").install();', 
      raw: true, 
      entryOnly: false 
    })
  ],
  .. 
}

We are done

Did you get stuck somewhere? Please don’t hesitate to email me or tweet me and I will help you! Webpack is a little bit tricky and sometimes so it’s useful with help when getting stuck.

 

Master the React ecosystem!

Get an email everytime I post by signing up to the email list.

Subscribe now and you will get a free code review checklist you can use to improve your own code