Webpack 热更新机制

前端精髓

共 1797字,需浏览 4分钟

 · 2021-08-12


热更新是啥?热更新,是指 Hot Module Replacement,缩写为 HMR。


微信小程序的开发工具,没有提供类似 Webpack 热更新的机制,所以在本地开发时,每次修改了代码,预览页面都会刷新,于是之前的路由跳转状态、表单中填入的数据,都没了。


而如果有类似 Webpack 热更新的机制存在,则是修改了代码,不会导致刷新,而是保留现有的数据状态,只将模块进行更新替换。也就是说,既保留了现有的数据状态,又能看到代码修改后的变化。


很美好,但是想想就觉得是一件肯定不简单的事情。


了解下热更新是怎么配置的。为 Webpack 开发环境开启热更新,要做两件事:

1、使用 HotModuleReplacementPlugin 插件

2、打开 webpack-dev-server 的热更新开关


HotModuleReplacementPlugin 插件是 Webpack 自带的,在 webpack.config.js 加入就好:

// webpack.config.jsmodule.exports = {  // ...  plugins: [    webpack.HotModuleReplacementPlugin(),   // ...  ]}


打开 webpack-dev-server 的热更新开关:

// webpack.config.jsmodule.exports = {  // ...  devServer: {    hot: true,    // ...  }}


下面通过例子来进一步解释热更新机制。如果你之前对 Webpack 热更新的体验,是 Vue 通过 vue-loader 提供给你的,也就是说你在自己的代码中从没有写过或者见到过类似:

import './client';let root = document.getElementById('root');function render() {  let title = require('./title').default;  root.innerHTML = title;}render();
if (module.hot) { module.hot.accept(['./title'], () => { render(); });}


Webpack 将热更新相关接口以 module.hot 暴露到模块中,在使用前,最好判断下当前的环境是否支持热更新,也就是上面看到的这样的代码。


所以,在热更新的机制中,其实是以这种“声明”的方式告知 Webpack,哪些模块的更新是被处理的,哪些模块的更新又不被处理。当然对于要处理的模块的更新,自行在 module.hot.accept() 的第二个参数即回调函数中进行处理,会在声明的模块被替换后执行。


此外,除了声明其他模块更新的处理,模块也可以声明自身更新的处理,也是同样的接口,不传参数即可:

1、module.hot.accept() 告诉 Webpack,当前模块更新不用刷新

2、module.hot.decline() 告诉 Webpack,当前模块更新时一定要刷新


而且,依赖同一个模块的不同模块,可以有各自不同的声明,这些声明可能是冲突的,比如有的允许依赖模块更新,有的不允许,Webpack 怎么协调这些呢?


Webpack 的实现机制有点类似 DOM 事件的冒泡机制,更新事件先由模块自身处理,如果模块自身没有任何声明,才会向上冒泡,检查使用方是否有对该模块更新的声明,以此类推。如果最终入口模块也没有任何声明,那么就刷新页面了。这也就是为什么在上一个例子中,虽然开启了热更新,但是模块修改后仍旧刷新页面的原因,因为没有任何模块对更新进行处理。


当然,像我们在使用 Vue 或 React 进行开发时,vue-loder 等插件已经帮我们做了这些事情,并且对于 *.vue 文件在更新时要如果进行处理,很多细节也只有 vue-loader 内部比较清楚,我们就放心使用好了。


浏览 8
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报