Webpack中文文档:
模块热替换 | webpack 中文文档
:::info
webpack-dev-server隐藏的特性:webpack-dev-server依然帮我们打包成一个dist目录只不过存在于电脑的内存当中,这样有效的提升了打包的速度。
:::
什么是HMR(hot-module-replacement)热模块替换?**HMR**就是在更改代码的时候页面内容发生变化但是不进行页面刷新。
CSS 热更新
import "./style.css";var btn = document.createElement("button");btn.innerHTML = "新增";btn.addEventListener("click", function () {var div = document.createElement("div");div.innerHTML = "item";document.body.appendChild(div);})document.body.appendChild(btn);
div:nth-of-type(odd) {background-color: antiquewhite;}

以上代码实现了当我点击页面的button按钮的时候就往页面进行一个div,div的背景色为antiquewhite,但是加入我把div样式文件替换成pink后,页面就进行了刷新,我们新增的item也被丢失了,而热模块替换就是解决这个问题的。
div:nth-of-type(odd) {background-color: pink;}
配置
方法一:直接配置devServer
module.exports = {// ...devServer: {contentBase: "./dist",open: true,hot: true, // 让 webpack-dev-server 开启 HMR 的功能hotOnly: true, // 即便 css 样式没有生效也不让浏览器自动刷新页面},}
方法二:实例化webpack.HotModuleReplacementPlugin()构造函数
const webpack = require("webpack");module.exports = {// ...devServer: {contentBase: "./dist",open: true,hot: true, // 让 webpack-dev-server 开启 HMR 的功能hotOnly: true, // 即便css样式没有生效也不让浏览器自动刷新页面},// ...plugins: [new webpack.HotModuleReplacementPlugin();]}
然后我们进行样式修改后就会发现页面的样式进行了改变,页面也没有刷新,我新增的item也没有丢失,仅仅是item的背景颜色发生了改变,这样就极大了提示我们的开发效率。
div:nth-of-type(odd) {background-color: aquamarine;}

JS 热更新
同样的效果也适用于JS文件:
// import "./style.css";// var btn = document.createElement("button");// btn.innerHTML = "新增";// document.body.appendChild(btn);// btn.addEventListener("click", function () {// var div = document.createElement("div");// div.innerHTML = "item";// document.body.appendChild(div);// })import counter from './counter';import number from './number';counter();number();
export default function () {let 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 function () {let div = document.createElement("div");div.setAttribute("id", "number");div.innerHTML = "1000";document.body.appendChild(div);}

以上代码我们能实现在页面上显示 1 和 1000,假设现在点击 1 就会自加 1 到10,接着去修改number.js中的 1000 为 2000 的时候,页面没有进行刷新,依然是 10 和 1000(如果没有开启热更新,当修改为 2000 的时候,页面就会刷新为 1 和 1000)。
如果解决这个问题呢?
import number from './number';import counter from './counter';counter();number();// 如果当前项目开启了热更新if (module.hot) {// 执行回调函数module.hot.accept("./number.js", () => {// 移除之前的 number,重新执行一下 number()document.body.removeChild(document.getElementById("number"));number();})}
现在点击 1 自加到任何数值,去代码里修改number.js中的 数字,页面就只会更新number.js ,不会影响counter元素。
:::warning
为什么js文件需要手动执行呢,而css文件就不需要呢?
这是因为css-loader已经帮我们做了这个操作,还有vue-loader也在内部帮我们做了这个操作。
:::
