Skip to content

Commit 81b5eac

Browse files
authored
Make example config more consistent
Previously, the config had been split between the config.js file and the CLI; everything has been moved into the config file. The explanation for the config entries was moved inline, as comments.
1 parent 40a0beb commit 81b5eac

File tree

1 file changed

+108
-35
lines changed

1 file changed

+108
-35
lines changed

content/how-to/hot-module-reload.md

Lines changed: 108 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
---
22
title: How to Configure Hot Module Replacement?
33
---
4-
Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running without a page reload. HMR is particularly useful in applications using a single state tree, since components are "dumb" and will reflect the latest application state, even after their source is changed and they are replaced.
5-
6-
Webpack's power lies in its customizablity, and there are MANY ways of configuring HMR given the needs of a particular project. The approach described below uses Babel and React, but these tools are not necessary for HMR to work. If you'd like to see examples of other approaches, please request them or, better yet, open up a PR with an addition!
4+
Hot Module Replacement (HMR) exchanges, adds, or removes modules while an
5+
application is running without a page reload.
6+
HMR is particularly useful in applications using a single state tree,
7+
since components are "dumb" and will reflect the latest application state, even
8+
after their source is changed and they are replaced.
9+
10+
Webpack's power lies in its customizablity, and there are MANY ways of configuring HMR
11+
given the needs of a particular project. The approach described below uses Babel and
12+
React, but these tools are not necessary for HMR to work.
13+
If you'd like to see examples of other approaches,
14+
please request them or, better yet,
15+
[open up a PR with an addition](https://github.com/webpack/webpack.io)!
716

817
##Project Config
9-
This guide will be demonstrating the use of HMR with Babel, React, and PostCSS (using CSS Modules). To follow along, please add the following deps to your `package.json`:
18+
This guide will be demonstrating the use of HMR with Babel,
19+
React, and PostCSS (using CSS Modules).
20+
To follow along, please add the following deps to your `package.json`:
1021

1122
To use HMR, you'll need the following dependencies:
1223

@@ -17,7 +28,7 @@ npm install --save-dev [email protected] [email protected] [email protected] babel-pr
1728
In addition, for the purposes of this walkthrough, you'll need:
1829

1930
```shell
20-
31+
2132
```
2233

2334

@@ -27,10 +38,10 @@ Your `.babelrc` file should look like the following:
2738
```js
2839
{
2940
"presets": [
30-
["es2015", {"modules": false}],
41+
["es2015", {"modules": false}],
3142
//Webpack understands the native import syntax, and uses it for tree shaking
3243

33-
"stage-2",
44+
"stage-2",
3445
//Specifies what level of language features to activate.
3546
//State 2 is "draft", 4 is finished, 0 is strawman.
3647
//See https://tc39.github.io/process-document/
@@ -46,62 +57,104 @@ Your `.babelrc` file should look like the following:
4657
```
4758

4859
###Webpack config
49-
While there's many ways of setting up your Webpack config - via API, via multiple or single config files, etc - here is the basic information you should have available:
60+
While there's many ways of setting up your Webpack config - via API,
61+
via multiple or single config files, etc - here is the basic information
62+
you should have available.
5063

5164
```js
5265
const { resolve } = require('path');
5366
const webpack = require('webpack');
5467

55-
const ENTRY = ['./index.js'];
56-
5768
module.exports = env => {
5869
return {
59-
entry: env.dev?
60-
[
61-
'react-hot-loader/patch',
62-
'webpack-dev-server/client?http://localhost:8080',
63-
'webpack/hot/only-dev-server',
64-
].concat(ENTRY)
65-
:
66-
ENTRY,
70+
entry: [
71+
'react-hot-loader/patch',
72+
//activate HMR for React
73+
74+
'webpack-dev-server/client?http://localhost:8080',
75+
//bundle the client for webpack dev server
76+
//and connect to the provided endpoint
77+
78+
'webpack/hot/only-dev-server',
79+
//bundle the client for hot reloading
80+
//only- means to only hot reload for successful updates
81+
82+
83+
'./index.js'
84+
//the entry point of our app
85+
],
6786
output: {
6887
filename: 'bundle.js',
88+
//the output bundle
89+
6990
path: resolve(__dirname, 'dist'),
91+
7092
publicPath: '/'
93+
//necessary for HMR to know where to load the hot update chunks
7194
},
95+
7296
context: resolve(__dirname, 'src'),
73-
devtool: env.prod ? 'source-map' : 'inline-source-map',
97+
98+
devtool: 'inline-source-map',
99+
74100
devServer: {
75101
hot: true,
102+
//activate hot reloading
103+
104+
contentBase: '/dist'
105+
//match the output path
106+
76107
publicPath: '/'
108+
//match the output publicPath
77109
},
110+
78111
module: {
79112
loaders: [
80-
{ test: /\.js$/, loader: 'babel',
81-
exclude: /node_modules/ },
113+
{ test: /\.js$/,
114+
loaders: [
115+
'babel',
116+
],
117+
exclude: /node_modules/
118+
},
82119
{
83120
test: /\.css$/,
84-
loader: 'style!css-loader?modules&postcss-loader',
121+
loaders: [
122+
'style',
123+
'css-loader?modules',
124+
'postcss-loader',
125+
],
85126
},
86127
],
87128
},
129+
88130
plugins: [
89131
new webpack.HotModuleReplacementPlugin(),
132+
//activates HMR
133+
90134
new webpack.NamedModulesPlugin(),
135+
//prints more readable module names in the browser console on HMR updates
91136
],
92137
}
93138
};
94139
```
95140

96-
There's a lot going on above, and not all of it is related to HMR. If you are new to Webpack configs, please see the documentation elsewhere on this site. The basic assumption here is that your JS entry is located at `./src/index.js`, and that you're using CSS Modules for your styling. Let's look at the HMR specific items.
141+
There's a lot going on above, and not all of it is related to HMR.
142+
You may benefit from reading the
143+
[full documentation](https://webpack.github.io/docs/webpack-dev-server.html)
144+
on webpack dev server, and the [other articles](https://webpack.github.io/webpack.io/concepts/)
145+
here on webpack.io.
97146

98-
First, the plugins. While only the HMRPlugin itself is necessary to enable HMR, the NamedModulesPlugin will make your life easier by showing an intelligible module id in your browser console whenever a file is changed.
147+
The basic assumption here is that your JS entry is located at `./src/index.js`,
148+
and that you're using CSS Modules for your styling.
99149

100-
Next, working backward, is the `devServer` key. While it's possible to configure webpack-dev-server directly from the CLI, or more specifically in a server script from the Node module API, this example approach is using the `devServer` key in the overall webpack config. `hot: true` turns on HMR. `publicPath` denotes the root from wich the server will serve up your code (e.g. `localhost:8080${PUBLIC_PATH}`, so in this case `localhost:8080/`). the `publicPath` should match the `output.publicPath`.
150+
Please see the comments inline that explain each portion of the config. The main
151+
areas to look are the `devServer` key and the `entry` key. The `HotModuleReplacementPlugin` is
152+
also necessary to include in the `plugins` array.
101153

102-
Finally, your entry file should be preceded by the elements included here: `'react-hot-loader/patch'`, `'webpack-dev-server/client?http://localhost:8080'`, and `'webpack/hot/only-dev-server'`. The react-hot-loader entry is only necessary if you are using React. The `webpack-dev-server/client?` line should make sure to point at the dev server instance you are running (in case you have configured a different port, for example). Finally, the `only` in `hot/only-dev-server` means that updates will only be sent on clean builds/bundles; you can drop the `only-` if you would prefer seeing error output in your browser via HMR.
103-
104-
The module loaders in this config, while not specific to HMR, are worth noting here; we're making sure to use Babel (as configued in the .babelrc) for our JS files, and setting up CSS Modules for our CSS code.
154+
There are two modules included here for the purposes of this guide.
155+
The react-hot-loader addition to the entry, as noted above, is necessary to enable
156+
HMR with React components. The NamedModulesPlugin is a useful addition
157+
to better understand what modules are being updated when using HMR.
105158

106159
###Code
107160
In this guide, we're using the following files:
@@ -154,23 +207,42 @@ export default App;
154207
}
155208
```
156209

157-
Now, the above code is using React, but it doesn't need to be. In fact, the only thing that matters above is the code refering to `module`. First, we wrap the HMR code inside of `module.hot` check; webpack exposes `module` to the code, and if we are running with `hot: true` configured, we'll enter the inside of the conditional. While the module API offers more options than what's above, the most important element is the `module.hot.accept` call. It specific how to handle changes to specific dependencies. So in this, it will file the `render` method ONLY when `src/components/App.js` changes! Note that would also include when the dependencies of `App.js` change - so the `render` method will file not just for changes made directly to the source of `App.js`, but also changes made to `App.css`, since `App.css` is included in `App.js`.
210+
Now, the above code is using React, but it doesn't need to be. In fact,
211+
the only thing that matters above is the code refering to `module`.
212+
First, we wrap the HMR code inside of `module.hot` check;
213+
webpack exposes `module` to the code, and if we are running with `hot: true` configured,
214+
we'll enter the inside of the conditional.
215+
216+
While the module API offers more options than what's above, the most
217+
important element is the `module.hot.accept` call.
218+
It specific how to handle changes to specific dependencies.
219+
220+
So in this case, `module.hot` will fire the `render` method ONLY
221+
when `src/components/App.js` changes! Note that would also include when the
222+
dependencies of `App.js` change -
223+
so the `render` method will file not just for changes made directly to the
224+
source of `App.js`, but also changes made to `App.css`, since `App.css`
225+
is included in `App.js`.
158226

159227
###Package.json
160-
Finally, we need to start up webpack dev server to bundle our code and see HMR in action. We can use the following package.json entry:
228+
Finally, we need to start up webpack dev server to bundle our code and see HMR in action.
229+
We can use the following package.json entry:
161230

162231
```js
163-
"start" : "webpack-dev-server --env.dev --content-base dist",
232+
"start" : "webpack-dev-server --env.dev",
164233
```
165234

166-
Run `npm start`, open up your browser to `localhost:8080`, and you should see the folling entries printed in your console.log:
167-
```
235+
Run `npm start`, open up your browser to `localhost:8080`,
236+
and you should see the folling entries printed in your console.log:
237+
238+
```
168239
dev-server.js:49[HMR] Waiting for update signal from WDS...
169240
only-dev-server.js:74[HMR] Waiting for update signal from WDS...
170241
client?c7c8:24 [WDS] Hot Module Replacement enabled.
171242
```
172243

173-
Go ahead and edit and save your App.js file. You should see something like the following in your console.log:
244+
Go ahead and edit and save your App.js file.
245+
You should see something like the following in your console.log:
174246

175247
```
176248
[WDS] App updated. Recompiling...
@@ -180,6 +252,7 @@ log-apply-result.js:20 [HMR] Updated modules:
180252
log-apply-result.js:22 [HMR] - ./components/App.js
181253
dev-server.js:27 [HMR] App is up to date.
182254
```
183-
Note that HMR specifies the paths of the updated modules. That's because we're using the NamedModules plugin!
255+
Note that HMR specifies the paths of the updated modules.
256+
That's because we're using the NamedModules plugin!
184257

185258

0 commit comments

Comments
 (0)