热模块更新

https://www.webpackjs.com/concepts/hot-module-replacement/

https://www.webpackjs.com/api/hot-module-replacement/

Hot Module Replacement 热模块更新(替换)HMR

package.json

1
2
3
"scripts": {
  "start": "webpack-dev-server"
},

lesson/webpack.config.js

 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
33
module: {
  rules: [{
    test: /\.(jpg|pnd|gif)$/,
    use: {
      loader: 'url-loader',
      options: {
        name: '[name]_[hash].[ext]',
        outputPath: 'images/',
        limit: 20480
      }
    }
  },{
    test: /\.scss$/,
    use: [
      'style-loader', 
      {
        loader: 'css-loader',
        options: {
          importLoaders: 2
        }
      },
      'sass-loader',
      'postcss-loader'
    ]
  },{
    test: /\.css$/,
    use: [
      'style-loader', 
      'css-loader',
      'postcss-loader'
    ]
  }]
},

src/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import './style.css'

var btn = document.createElement('button');
btn.innerHTML = '新增';
document.body.appendChild(btn);

btn.onclick = function() {
  var div = document.createElement('div');
  div.innerHTML = 'item';
  document.body.appendChild(div);
}

src/style.css

1
2
3
div:nth-of-type(odd) {
  background: blue;
}
1
➜  lesson npm run start

启动服务器

启动服务器后,打包后的文件不会放到dist目录,而是放在内存中

每次修改保存之后都会自动刷新页面,页面上新增的div就会消失

我们希望修改样式时,不要刷新页面,而是将样式进行修改

修改`lesson/webpack.config.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const webpack = require('webpack');

devServer: {
  contentBase: './dist',
  open: true,
  hot: true,
  hotOnly: true,
},

plugins: [
  new CleanWebpackPlugin(),
  new HtmlWebpackPlugin({
    template: 'src/index.html'
  }),
  new webpack.HotModuleReplacementPlugin()
],

修改配置后,重启服务器

1
➜  lesson npm run start

这时修改样式时,不会刷新页面,新增的item依然存在,只会修改页面上的样式
方便调试css

lesson/src/number.js

1
2
3
4
5
6
7
function number() {
  var div = document.createElement('div');
  div.setAttribute('id', 'number');
  div.innerHTML = 1000;
  document.body.appendChild(div);
}
export default number;

lesson/src/counter.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function counter() {
  var div = document.createElement('div');
  div.setAttribute('id', 'counter');
  div.innerHTML = 1;
  div.onclick = function() {
    div.innerHTML = parseInt(div.innerHTML, 10) + 1;
  }
  document.body.appendChild(div);
}
export default counter;

index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import counter from './counter';
import number from './number';

counter();
number();

// if (module.hot) {
//   module.hot.accept('./number', () => {
//     number();
//   })
// }

if (module.hot) {
  module.hot.accept('./number', () => {
    document.body.removeChild(document.getElementById('number'));
    number();
  })
}