Skip to content

Hot reload client and server webpack bundles for the ultimate development experience

License

Notifications You must be signed in to change notification settings

Alex-Ferreli/universal-hot-reload

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

universal-hot-reload

npm version npm downloads npm npm

Hot reload universally bundled webpack apps for the ultimate development experience 👏

Update 26/3/18: Now works with webpack 4 and babel 7.

FOR DEVELOPMENT USE ONLY!

If you universally bundle your app using webpack (i.e. you use webpack to bundle your server AND client side code) this package will set up hot reloading for both server and client side.

What you get from this package:

  • Automatic re-bundle on server code changes so server side rendering always reflect the latest changes.
  • Automatic re-bundle on client code changes using webpack-serve.

Installation

yarn add universal-hot-reload -D

Quickstart

  1. Setup your server bundle webpack config like below. The important parts are:

    • Set target to node.
    • Excluding node_modules from the server bundle by setting externals using webpack-node-externals.
    • Set libraryTarget to commonjs2 which adds module.exports to the beginning of the bundle, so universal-hot-reload can access your app.
    const path = require('path');
    const nodeExternals = require('webpack-node-externals');
    
    module.exports = {
      mode: 'development',
      devtool: 'source-map',
      entry: './src/server/server.js',
      target: 'node', // Important
      externals: [nodeExternals()], // Important
      output: {
        path: path.resolve('dist'),
        filename: 'serverBundle.js',
        libraryTarget: 'commonjs2' // Important
      },
    
      // other standard webpack config like loaders, plugins, etc...
    };
  2. Setup your client bundle webpack config like below. Note that in output, publicPath must be the full url to the bundle:

    const path = require('path');
    const webpackServeUrl = 'http://localhost:3002';
    
    module.exports = {
      mode: 'development',
      devtool: 'source-map',
      entry: './src/client/index',
      output: {
        path: path.resolve('dist'),
        publicPath: `${webpackServeUrl}/dist/`, // MUST BE FULL PATH!
        filename: 'bundle.js'
      },
      module: {
        rules: [
          {
            test: /\.jsx?$/,
            loader: 'babel-loader',
            include: path.resolve('src'),
            exclude: /node_modules/,
            options: {
              cacheDirectory: true,
            }
          }]
      },
    };
  3. In your server bootstrap, require universal-hot-reload and invoke it, passing it your server and client webpack config objects in that order:

    const UniversalHotReload = require('universal-hot-reload').default;
    
    UniversalHotReload(require('path/to/webpack.server.config.js'),
                       require('path/to/webpack.client.config.js'));
  4. In your server entry file (as specified in your webpack server config "entry" property):

    • In your html template for server rendering, the script reference to the client bundle should point to webpackServeUrl/dist/bundle.js.
    • You must export your express app so universal-hot-reload can access the http.server object
    import express from 'express';
    
    const PORT = 3000;
    const app = express();
    app.use('/dist', express.static('dist', {maxAge: '1d'}));
    
    // Important: reference webpack serve url for the client bundle
    const html = `<!DOCTYPE html>
                <html>
                  <body>
                    <div id="reactDiv">${reactString}</div>
                    <script src="http://localhost:3002/dist/bundle.js"></script>
                  </body>
                </html>`;
                
    // Important: the listen method returns a http.server object which must be exported
    const httpServer = app.listen(PORT, () => {
      log.info(`Listening at ${PORT}`);
    });
    
    // export http.server object so universal-hot-reload can access it
    module.exports = httpServer;
  5. Run your app!

    node src/server/index.js

Example

Check the example for a fully working spa with react and react-router.

About

Hot reload client and server webpack bundles for the ultimate development experience

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%