Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
9853fa2
Create new hot-module-reloading doc
jmreidy Aug 5, 2016
69fccee
First cut of HMR documentation
jmreidy Aug 5, 2016
07161de
Update project config section
jmreidy Aug 9, 2016
bee36a8
Fix spelling mistakes
jmreidy Aug 9, 2016
40a0beb
Update .babelrc section
jmreidy Aug 9, 2016
81b5eac
Make example config more consistent
jmreidy Aug 11, 2016
96e4dea
Fix typos
therobinkim Aug 20, 2016
5a63de5
Merge pull request #69 from therobinkim/therobinkim/typos
bebraw Aug 20, 2016
31dda53
add contributing.md file with instructions
jschwarty Aug 21, 2016
b190a1b
fix links, cd path, add bold styling
jschwarty Aug 21, 2016
1dabdc9
swap order of changes types to be consistent
jschwarty Aug 21, 2016
8280dcd
remove code contribs info, add develop branch info
jschwarty Aug 21, 2016
8745539
Merge pull request #72 from jschwarty/feature/add-contributing-file
TheLarkInn Aug 21, 2016
c7c5567
Update README.md
TheLarkInn Aug 21, 2016
3e0755b
docs(concepts): added new targets section (#71)
TheLarkInn Aug 24, 2016
5a2e228
Use Ubuntu Mono for code blocks
skipjack Aug 24, 2016
c4d390c
Added Long-term caching page
okonet Aug 25, 2016
838c5bb
[fix] Fixing misspelled language and adding missing commas
skipjack Aug 26, 2016
c04eb41
[fix] Minor fix in logo styling
skipjack Aug 26, 2016
1808be8
[fix] Update antwar (fixes #76)
skipjack Aug 26, 2016
b3e6d35
Documentation for webpack cli
Aug 26, 2016
fd21551
Documentation for how to develop using Vagrant
SpaceK33z Aug 27, 2016
cac8833
Add correct code lang blocks
SpaceK33z Aug 27, 2016
986004d
Implement PR feedback
SpaceK33z Aug 28, 2016
dc8ebf5
Merge pull request #78 from SpaceK33z/feature/add-develop-using-vagra…
bebraw Aug 28, 2016
ccb15a8
develop using vagrant - using -> Using, bash -> sh
bebraw Aug 28, 2016
ab0dce4
Move HMR walkthrough to React section
jmreidy Aug 29, 2016
e795740
Capitalize text for all headers
okonet Aug 30, 2016
60e8e3b
Better code formatting
okonet Aug 30, 2016
7e740b0
Merge pull request #83 from okonet/feature/text-capitalize
bebraw Aug 30, 2016
2577b71
Use webpack.io specific markup for tips and warnings
okonet Aug 30, 2016
147ae28
Added link to the original Medium article
okonet Aug 30, 2016
c661b01
Merge pull request #75 from okonet/feature/long-term-caching
bebraw Aug 30, 2016
ccdfc34
Merge caching articles
bebraw Aug 30, 2016
ce78a71
Update progress
bebraw Aug 30, 2016
6e7ed53
Fix progress color
bebraw Aug 30, 2016
60283b9
Add initial content for how-to/generate-produciton-build (#73)
riqswe Aug 30, 2016
a9f00cd
Update progress
bebraw Aug 30, 2016
c1cce0e
Add "done" sections
bebraw Aug 30, 2016
bd16791
Implements review comments
Aug 30, 2016
acd97fc
Spacing corrections
Aug 30, 2016
8c14773
Merge pull request #77 from kalcifer/develop
bebraw Aug 30, 2016
6349dc5
Fix todos
bebraw Aug 30, 2016
30b37c9
Push cli to done
bebraw Aug 30, 2016
1f2b0fe
[fix] Changing all `sh` to `bash` to fix prism unsupported language e…
skipjack Aug 31, 2016
421a25c
[fix] Updating the error catching in highlight.js for clarity
skipjack Aug 31, 2016
2eec99b
Small spelling fix in Contributing.md
skipjack Aug 31, 2016
aad86cb
Minor formatting change
skipjack Aug 31, 2016
850ec59
[fix] Preventing anything in Page from overflowing it's allowed width
skipjack Aug 31, 2016
7801bf0
Adds a how to for webpack installation
Aug 31, 2016
954c7cc
Review comments
Aug 31, 2016
6177520
Merge pull request #64 from jmreidy/content-howto-hmr
bebraw Aug 31, 2016
5de6432
State -> Stage
bebraw Aug 31, 2016
c04a950
Improve React HMR Article Naming
bebraw Aug 31, 2016
27ac882
[fix] Changing `shell`s to `bash` to prevent prism errors
skipjack Sep 2, 2016
e76fb81
Review comments
Sep 4, 2016
224859c
Merge pull request #84 from kalcifer/develop
bebraw Sep 4, 2016
2a28664
Lint through proselint
bebraw Sep 4, 2016
e418c46
[fix] Changing "sh" to "bash" to fix prism errors
skipjack Sep 4, 2016
b91b64b
Adding another shade of grey
skipjack Aug 28, 2016
8497249
Updating the base font color
skipjack Sep 4, 2016
6e7e1ad
Tweaking horizontal rule styling...
skipjack Sep 4, 2016
f63973a
feat(eslint): add eslint for markdown js codeblocks
TheLarkInn Sep 6, 2016
6a08ded
Merge pull request #97 from TheLarkInn/feature/add_eslint_to_markdown…
bebraw Sep 6, 2016
ed56f7c
Tweaking hr styling (again probably temporary)
skipjack Sep 6, 2016
340b7bd
Removing capitalization for all headers, this prevents things like "W…
skipjack Sep 6, 2016
e30e9af
Rename everything-is-a-module to modules
bebraw Sep 7, 2016
4625c3b
create CNAME file for domain
sokra Sep 7, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move HMR walkthrough to React section
  • Loading branch information
jmreidy committed Aug 29, 2016
commit ab0dce47b32bd08fd886f71539955c384d2d8c03
252 changes: 252 additions & 0 deletions content/how-to/hmr/hot-module-reload-with-react.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
---
title: How to Configure Hot Module Replacement with React?
---
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.

##Project Config
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`:

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

```shell
npm install --save-dev [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]
```

In addition, for the purposes of this walkthrough, you'll need:

```shell
npm install --save [email protected] [email protected]
```


###Babel Config
Your `.babelrc` file should look like the following:

```js
{
"presets": [
["es2015", {"modules": false}],
//Webpack understands the native import syntax, and uses it for tree shaking

"stage-2",
//Specifies what level of language features to activate.
//State 2 is "draft", 4 is finished, 0 is strawman.
//See https://tc39.github.io/process-document/

"react"
//Transpile React components to JS
],
"plugins": [
"react-hot-loader/babel"
//Enables React code to work with HMR.
]
}
```

###Webpack config
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.

```js
const { resolve } = require('path');
const webpack = require('webpack');

module.exports = env => {
return {
entry: [
'react-hot-loader/patch',
//activate HMR for React

'webpack-dev-server/client?http://localhost:8080',
//bundle the client for webpack dev server
//and connect to the provided endpoint

'webpack/hot/only-dev-server',
//bundle the client for hot reloading
//only- means to only hot reload for successful updates


'./index.js'
//the entry point of our app
],
output: {
filename: 'bundle.js',
//the output bundle

path: resolve(__dirname, 'dist'),

publicPath: '/'
//necessary for HMR to know where to load the hot update chunks
},

context: resolve(__dirname, 'src'),

devtool: 'inline-source-map',

devServer: {
hot: true,
//activate hot reloading

contentBase: '/dist'
//match the output path

publicPath: '/'
//match the output publicPath
},

module: {
loaders: [
{ test: /\.js$/,
loaders: [
'babel',
],
exclude: /node_modules/
},
{
test: /\.css$/,
loaders: [
'style',
'css-loader?modules',
'postcss-loader',
],
},
],
},

plugins: [
new webpack.HotModuleReplacementPlugin(),
//activates HMR

new webpack.NamedModulesPlugin(),
//prints more readable module names in the browser console on HMR updates
],
}
};
```

There's a lot going on above, and not all of it is related to HMR.
You may benefit from reading the
[full documentation](https://webpack.github.io/docs/webpack-dev-server.html)
on webpack dev server, and the [other articles](https://webpack.github.io/webpack.io/concepts/)
here on webpack.io.

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.

Please see the comments inline that explain each portion of the config. The main
areas to look are the `devServer` key and the `entry` key. The `HotModuleReplacementPlugin` is
also necessary to include in the `plugins` array.

There are two modules included here for the purposes of this guide.
The react-hot-loader addition to the entry, as noted above, is necessary to enable
HMR with React components. The NamedModulesPlugin is a useful addition
to better understand what modules are being updated when using HMR.

###Code
In this guide, we're using the following files:

```js
// ./src/index.js
import React from 'react';
import ReactDOM from 'react-dom';

import { AppContainer } from 'react-hot-loader'
// AppContainer is a necessary wrapper component for HMR

import App from './components/App';

const render = () => {
ReactDOM.render(
<AppContainer>
<App/>
</AppContainer>,
document.getElementById('root')
);
};

render();

// Hot Module Replacement API
if (module.hot) {
module.hot.accept('./components/App', render);
}


// ./src/components/App.js
import React from 'react';
import styles from './App.css';

const App = () => (
<div className={styles.app}>
<h2>Hello, </h2>
</div>
);

export default App;
```

```css
// ./src/components/App.css
.app {
text-size-adjust: none;
font-family: helvetica, arial, sans-serif;
line-height: 200%;
padding: 6px 20px 30px;
}
```

The important thing to note in the code above is the `module` reference.
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 case, `module.hot` will fire 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`.

###Package.json
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:

```js
"start" : "webpack-dev-server --env.dev",
```

Run `npm start`, open up your browser to `localhost:8080`,
and you should see the folling entries printed in your console.log:

```
dev-server.js:49[HMR] Waiting for update signal from WDS...
only-dev-server.js:74[HMR] Waiting for update signal from WDS...
client?c7c8:24 [WDS] Hot Module Replacement enabled.
```

Go ahead and edit and save your App.js file.
You should see something like the following in your console.log:

```
[WDS] App updated. Recompiling...
client?c7c8:91 [WDS] App hot update...
dev-server.js:45 [HMR] Checking for updates on the server...
log-apply-result.js:20 [HMR] Updated modules:
log-apply-result.js:22 [HMR] - ./components/App.js
dev-server.js:27 [HMR] App is up to date.
```
Note that HMR specifies the paths of the updated modules.
That's because we're using the NamedModules plugin!