摘要
本文主要讲述了:
- 什么是 HMR
- JavaScript
- CSS
正文
什么是 HMR
启动webpack-dev-server
之后,当模块内容发生变化时,webpack-dev-server
默认情况下会自动进行完全重载。项目小的时候这样做还不影响性能,但是当项目变大之后,每次完全重载可能需要花费过多的时间。由此 HMR 应运而生。
HMR,全称为 Hot Module Replacement(热模块替换)。
HMR 指的是,不需要完全重载,只需要更新变化了的部分。
注意:
- HMR 只适用于开发环境而不适用于生产环境
- 不要在开发环境的配置文件中配置
[hash]
、[chunkhash]
等文件名占位符,这很可能会导致内存泄漏
JavaScript
示例:
learn_webpack/webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = { mode: 'development', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', }, devServer: { hot: true, }, plugins: [ new HtmlWebpackPlugin({ title: 'learn_webpack', template: 'public/index.html', }), ], };
|
learn_webpack/public/index.html
1 2 3 4 5 6 7 8 9 10
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body></body> </html>
|
learn_webpack/src/index.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
| import printMe from './print.js';
function component() { const element = document.createElement('div'); const btn = document.createElement('button');
element.innerHTML = 'hello, jsweibo';
btn.innerHTML = 'Click me and check the console!'; btn.onclick = printMe;
element.appendChild(btn);
return element; }
let element = component(); document.body.appendChild(element);
if (module.hot) { module.hot.accept('./print.js', function () { console.log('Accepting the updated printMe module!'); }); }
|
learn_webpack/src/print.js
1 2 3
| module.exports = function () { console.log('print me!'); };
|
devServer 启动后,如果修改print.js
,例如下面这样:
learn_webpack/src/print.js
1 2 3
| module.exports = function () { console.log('print me, please!'); };
|
此时 HMR 将被触发。
但是,此时<button>
点击事件的回调函数依然在旧的print.js
上。因此,还需要对index.js
做一点修改。
learn_webpack/src/index.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
| import printMe from './print.js';
function component() { const element = document.createElement('div'); const btn = document.createElement('button');
element.innerHTML = 'hello, jsweibo';
btn.innerHTML = 'Click me and check the console!'; btn.onclick = printMe;
element.appendChild(btn);
return element; }
let element = component(); document.body.appendChild(element);
if (module.hot) { module.hot.accept('./print.js', function () { console.log('Accepting the updated printMe module!');
document.body.removeChild(element); element = component(); document.body.appendChild(element); }); }
|
CSS
CSS 的 HMR 比起 JavaScript 要简单很多,因为 loader 已经替我们做了大量的工作。
learn_webpack/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 34 35
| const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = { mode: 'development', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', }, devServer: { hot: true, }, module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader', }, { loader: 'css-loader', }, ], }, ], }, plugins: [ new HtmlWebpackPlugin({ title: 'learn_webpack', template: 'public/index.html', }), ], };
|
learn_webpack/src/index.js
1
| import './css/style.css';
|
learn_webpack/src/css/style.css
devServer 启动后,如果修改style.css
,例如下面这样:
learn_webpack/src/css/style.css
此时 HMR 将被触发。
参考资料
本文对你有帮助?请支持我