聊一聊Webpack的热更新(HMR)
Webpack提供了一个很有用的功能,就是热更新(Hot Module Replacement,简称HMR)。热更新可以让我们在开发过程中,修改了某个模块的代码后,不需要刷新浏览器,就能看到最新的效果。这样可以大大提高开发效率和体验。那么,Webpack是如何实现热更新的呢?本文将从原理、运行机制和配置三方面来介绍。
热更新的原理
要实现热更新,首先需要有一个服务器(Server)和一个客户端(Client)。服务器负责监听文件的变化,并通知客户端。客户端负责接收服务器的通知,并根据需要替换或更新模块。Webpack提供了两种方式来实现这个功能:webpack-dev-server
和webpack-hot-middleware
。
webpack-dev-server
webpack-dev-server
是一个基于express的轻量级服务器,它可以在本地启动一个静态资源服务器,并且支持热更新。webpack-dev-server
内部使用了webpack-dev-middleware
和webpack-hot-middleware
两个中间件。webpack-dev-middleware
负责将webpack打包后的文件暂存到内存中,并提供给浏览器访问。webpack-hot-middleware
负责建立一个WebSocket连接,用于将文件变化的信息推送给浏览器。
webpack-hot-middleware
webpack-hot-middleware
是一个基于connect的中间件,它可以和任何基于connect或express的服务器配合使用,实现热更新功能。webpack-hot-middleware也是通过WebSocket来通信的,但是它不会将打包后的文件暂存到内存中,而是直接从硬盘读取。
运行机制
- 当源代码发生变化时,webpack会重新编译打包,并将变化的模块发送给客户端。
- 客户端接收到变化的模块后,会通过
HMR
runtime
和HMR api
来处理模块的替换。 HMR runtime
负责维护模块之间的依赖关系,以及通知HMR api
进行模块的更新。HMR api
负责根据模块的类型和接受状态,执行相应的替换逻辑,比如调用module.hot.accept
或module.hot.dispose
等方法。- 如果模块的替换成功,页面就可以实现局部更新;如果模块的替换失败,或者涉及到不支持
HMR
的模块,页面就会自动刷新。
如何启用HMR
下面是Webpack以及Vue不同版本的开启方式:
Webpack配置
- 在entry入口文件中添加webpack-hot-middleware/client或者webpack/hot/dev-server,这样可以在浏览器端创建一个客户端对象,用于接收服务器的通知。
// webpack.config.js module.exports = { entry: { app: ['webpack-hot-middleware/client', './src/index.js'], }, // ... };
- 在plugins插件中添加new webpack.HotModuleReplacementPlugin(),这样可以在编译时为每个模块添加一些代码,用于支持热更新。
// webpack.config.js const webpack = require('webpack'); module.exports = { // ... plugins: [ new webpack.HotModuleReplacementPlugin(), // ... ], };
- 在output输出中添加publicPath属性,指定打包后的文件在服务器上的访问路径。
// webpack.config.js module.exports = { output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), publicPath: '/', }, // ... };
- 在devServer开发服务器中添加hot属性,设置为true,表示启用热更新。
// webpack.config.js module.exports = { devServer: { contentBase: './dist', hot: true, }, // ... };
Vue-Cli3
使用 Vue CLI 3 可以通过 vue.config.js
文件来配置 webpack。下面是在 vue.config.js
中启用 HMR 的示例代码:
module.exports = {
configureWebpack: {
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
},
devServer: {
hot: true,
},
};
在上述代码中,我们在 configureWebpack
中添加了 HotModuleReplacementPlugin
插件,以启用热更新功能。在 devServer
中设置 hot
属性为 true
,表示启用热更新功能。
需要注意的是,如果你在 Vue CLI 3 中使用了多个 webpack 配置文件,则需要在对应的配置文件中进行相应的配置。
Vue-Cli4
// vue.config.js
module.exports = {
devServer: {
hot: true,
},
};
在 Vue CLI 4 及以上版本中,你不需要手动配置 HotModuleReplacementPlugin
插件,Vue CLI 会自动为你配置。
参考资料
转载自:https://juejin.cn/post/7230613183185682488