webpack热更新
概念
- 热更新类似于局部刷新,因此本质就是想办法拿到那些发生改变了的代码 ,然后重新打包到界面上
- webpack 内部实现了 HotModuleReplacement 插件,它可以生成二个文件,一个是 json , 一个是 js
- 第一次打包时不存在热更新,正常走打包逻辑,后续以 watch 的模式监听文件系统当中的文件变化
- 一旦某个文件发生了变更之后就会重新执行打包动作产出新的内容,然后再将内容变更通知到浏览器
- 浏览器获取到变更信息之后就会想办法来获取到实际发生了变更的文件内容,然后执行回调展示在界面上
- 在 webpack 的运行时中
__webpack__modules__
用以维护所有的模块。而热模块替换的原理,即通过chunk
的方式加载最新的modules
,找到__webpack__modules__
中对应的模块逐一替换,并删除其上下缓存。
使用
js// webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require("path"); module.exports = { target: 'web', mode: "development", entry: './index.js', output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') }, plugins: [ new HtmlWebpackPlugin({title: 'Hot Module Replacement'}) ], devtool: 'source-map', devServer: { // inline:false, // hot:false // hotOnly: true } }
-
启动webpack
webpack serve
-
打开浏览器,修改js,浏览器自动刷新
-
修改配置
inline置为true
-
修改代码,浏览器无刷新
原理
- 监听文件的变化,node的fs监听文件,触发重新编译,因为dev是存在内存中的,使用的是
memory-fs
,新文件产出之后如何通知到浏览器(基于 websocket 通信) - devServer通过websocket通知文件更新,将新模块的hash用json格式发送给浏览器
- 浏览器收到服务端发来的消息,收到type为hash的消息,存下hash,收到type为ok的消息,执行reload操作
- 如果配置了热更新,通过hash以jsonp方式执行热更新,没有热更新就刷新
- 先找出过期的模块及其依赖;从缓存中删除过期的模块和依赖;将新的模块添加到modules中
F&Q
hot
和hotOnly
的区别
hot与hotOnly都会开启HMR热更新,但是对于不支持HMR的资源hot会fallback刷新加载,hotOnly不会刷新加载,会报如上错误
- 在react项目中,css可以热更新,js不可以热更新
要自己配置
如果你遇到以下的问题
必须在入口文件加这个代码,否则热更新无效
jsif (module.hot) { module.hot.accept(); }
- 为什么css可以直接热更新,js不能直接热更新
style-loader
实现了热更新插件