携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
1.什么是模块热更新
作用:它允许在运行时替换,添加,删除各种模块, 当你对代码修改并保存后,webpack将会对代码进行重新打包,并将改动的模块发送到浏览器端,浏览器用新的模块替换掉旧的模块,去实现局部更新页面而非整体刷新页面, 而无需进行完全刷新重新加载整个页面。
其思路主要有以下几个方面:
- 保留在完全重新加载页面时丢失的应用程序的状态
- 只更新改变的内容,以节省开发时间
- 调整样式更加快速,几乎等同于就在浏览器调试器中更改样式
2.使用场景
一般情况下,一个模块发生变化,比如只改变一个css文件,js文件没有变化,最后还是全部都重新载 热模块更新就会 保留js的状态,只改变css文件
3.启动HRM
1.HotModuleReplacementPlugin 插件是 Webpack 自带的,
const webpack = require('webpack');
plugins: [ webpack.HotModuleReplacementPlugin(),]
2.直接通过 webpack-dev-server 启动 Webpack 的开发环境:
devServer: {hot: true,}
4.热更新处理文件
可以1.样式文件:
1.样式文件:可以使用HRM功能,style-loader内部实现了
2.js文件:js文件默认不能使用HRM功能
解决:修改js代码,添加支持HRM的代码
注意:模块热更新,不能用来主入口文件里,只能用在分支上面
3.html文件:html文件默认不能使用HRM功能,同时还会导致问题:html文件不能更新,改变了东西不能在页面改变
解决:修改entey入口,将html文件引入,依旧默认不能使用HRM功能
entry: ["./src/js/index.js", "./src/index.html"],
4.1 js文件使用HRM
1.没有热更新的情况
这个例子只是把示例页面的功能简单介绍下,并且让你体会下每次修改代码都要重新刷新页面的痛苦。
//改变timer.js的延迟时间时,计数会从0开始计数
import { start } from './timer'
start(Update, 0);
function Update(i) {
current = i
root.textContent = '#' + i // 修改数值渲染
}
2.依赖模块的热更新
接下来的例子,展示在 index.js 如何处理其他模块的更新。 module.hot.accept() 告诉 Webpack,当前模块更新不用刷新 module.hot.decline() 告诉 Webpack,当前模块更新时一定要刷新 在热更新的机制中,以这种“声明”的方式告知 Webpack, 哪些模块的更新是被处理的, 哪些模块的更新又不被处理
//改变timer.js的延迟时间时,计数会接着开始
var current = 0
var root = document.getElementById('root')
var stop = start(onUpdate, current)
if (module.hot) {
module.hot.accept('./timer', function () {
stop()
stop = start(onUpdate, current)
})
module.hot.decline('./foo')
}
function onUpdate(i) {
current = i
root.textContent = '#' + i // 修改数值渲染
}
3.处理自身模块
module.hot.dispose() 用于注册当前模块被替换前的处理函数,并且回调函数接收一个 data 对象,可以向其写入需要保存的数据,这样在新的模块执行时可以通过 module.hot.data 获取到: 首先,模块执行时,先检查有没有旧模块留下来的数据,如果有,就恢复。 然后在模块被替换前的执行处理,这里就是记录数据、停掉现有的定时器: 做了这些处理之后,修改 index.js 的 onUpdate,使得渲染到页面的数值改变,也可以在不刷新的情况下体现:
//在index.js中改变,计时器也会接着计时,不会从0开始
添加以下代码:
if (module.hot && module.hot.data) {
current = module.hot.data.current
}
module.hot.accept()
module.hot.dispose(data => {
data.current = current
stop()
})