Webpack HMR 原理解析

前端开发中,我们经常需要修改代码并刷新页面来看到效果,这种方式的效率和开发体验都很不理想。Webpack HMR(热更新)可以帮助我们实现快速的代码修改和实时预览,提高开发效率。本文将介绍 Webpack HMR 的原理,并给出详细的示例代码。

1. HMR 是什么?

HMR 是 Hot Module Replacement 的缩写,即热模块替换。其实现原理是 Webpack 监听文件变化,通过浏览器 Websocket 连接向客户端推送相应的代码模块,实现页面无需刷新即可响应新的修改。

2. HMR 原理

Webpack HMR 原理分为两个部分:

  1. 客户端部分:负责接收更新模块代码,处理新旧模块差异并更新页面 DOM。

  2. 服务端部分:负责构建模块依赖关系及其更新,将更新的模块和 hash 值通过 Websocket 推送到客户端。

2.1 客户端

客户端通过 module.hot.accept 方法来控制模块是否需要实时刷新。需要注意的是,module.hot.accept 这个 API 只是以 undefined 作为返回值,表明模块已经准备好了;实际上它不需要实际返回值,而且返回任何值都是合法的。

示例代码:

if (module.hot) {
  module.hot.accept('./foo.js', () => {
    // 执行回调函数
  })
}

2.2 服务端

我们可以在 Webpack 的配置中开启 HMR,然后在应用启动时调用 Webpack 的 compiler.watch 来监听文件变化。如果代码有变化,则会触发 compiler 对象上的 compile 事件。

示例代码:

const compiler = webpack(config);

if (process.env.NODE_ENV === 'development') {
  compiler.watch({}, (err, stats) => {
    if (err) throw err;
    console.log(stats.toString({ colors: true }));
  });
}

当监听到 compile 事件时,Webpack 会重新构建所有模块的依赖关系,并重新生成新的 hash 值。然后会检测每个模块的变化,构建一个新的模块映射表。最终将这个映射表通过 Websocket 传给浏览器端,让浏览器能够实时接收到最新代码。

3. HMR 实践

接下来我们通过实践来学习如何使用 Webpack HMR。

保证已经安装了 webpackwebpack-dev-server

3.1 创建项目

首先我们创建一个新的文件夹,并新建 index.htmlindex.jswebpack.config.js 文件。

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Webpack HMR</title>
</head>
<body>
  <h1 id="header"></h1>
  <script src="./index.js"></script>
</body>
</html>
// index.js
if (module.hot) {
  module.hot.accept({
    // 申明需要实时刷新的模块
    test: /\.js$/,
    // 需要执行的回调函数
    callback() {
      document.getElementById('header').textContent = 'Hello, Webpack HMR!';
    }
  });
}

document.getElementById('header').textContent = 'Hello, Webpack!';
// webpack.config.js
const path = require('path');

module.exports = {
  mode: 'development',
  entry: './index.js',
  devServer: {
    contentBase: './dist',
    hot: true, // 开启 HMR
  },
};

webpack.config.js 主要配置了打包入口、开发模式和 HMR 相关的设置。其中 devServer.hot 是开启 HMR 的关键,当它为 true 时,Webpack 会自动添加 HMR 监听。

3.2 运行项目

我们使用 npx webpack serve 即可在浏览器中运行我们的项目。

修改 index.js 的内容,可以看到 header 标签自动更新内容。

4. 总结

本文介绍了 Webpack HMR 的原理和实践,通过代码示例让大家了解了 HMR 的实现方式及应用场景。 HMR 目前已成为前端开发的必备技能之一,能够大大提高开发效率,值得学习和掌握。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ab225badd4f0e0ff4bce4d


纠错反馈