icyrock.com

Home

Javascript experiments - hot-module-replacement

2017-Aug-01 22:49
javascript-experimentsjavascriptnodewebpack

Webpack supports hot module replacement (HMR). It can be used to provide HMR to a server-side application very easily.

Our application is very simple:

1
2
3
exports.run = function() {
  console.log('App now running')
}

The server that will run it:

1
2
3
4
5
6
7
8
9
10
11
const runner = function() {
  const app = require('./app')
  app.run()
}
 
runner()
 
module.hot.accept('./app.js', function () {
  console.log('app.js module replacement accepted')
  runner()
})

Webpack configuration with HMR and server start enabled:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
const StartServerPlugin = require('start-server-webpack-plugin')
 
module.exports = {
  context: __dirname + '/src',
  entry: [
    'webpack/hot/poll?1000',
    './server',
  ],
  externals: [
    nodeExternals({
      whitelist: [
        'webpack/hot/signal',
        'webpack/hot/poll?1000'
      ]
    })
  ],
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js'
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
    new StartServerPlugin({
      name: 'bundle.js'
    })
  ],
  target: 'node',
}

Here are the packages needed in package.json:

1
2
3
4
5
6
7
8
9
10
11
{
  ...
  "devDependencies": {
    "start-server-webpack-plugin": "^2.2.0",
    "webpack": "^3.4.1",
    "webpack-hot-middleware": "^2.18.2",
    "webpack-node-externals": "^1.6.0",
    "webpack-shell-plugin": "^0.5.0"
  },
  ...
}

Sample invocation, with changing the log line in app.js by appending 'yay!':

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ webpack --watch
 
Webpack is watching the files…
 
Hash: 1f64b51e4ded543ed195
Version: webpack 3.4.1
Time: 174ms
    Asset     Size  Chunks             Chunk Names
bundle.js  30.3 kB       0  [emitted]  main
[./app.js] ./app.js 61 bytes {0} [built]
[./server.js] ./server.js 193 bytes {0} [built]
   [0] multi webpack/hot/poll?1000 ./server 40 bytes {0} [built]
    + 3 hidden modules
App now running
Hash: 0f743dbc4801ddd0993e
Version: webpack 3.4.1
Time: 28ms
                               Asset       Size  Chunks             Chunk Names
                           bundle.js    30.3 kB       0  [emitted]  main
0.1f64b51e4ded543ed195.hot-update.js  171 bytes       0  [emitted]  main
1f64b51e4ded543ed195.hot-update.json   43 bytes          [emitted] 
[./app.js] ./app.js 66 bytes {0} [built]
    + 5 hidden modules
app.js module replacement accepted
App now running yay!
[HMR] Updated modules:
[HMR]  - ./app.js
[HMR] Update applied.
^C
$