webpack实践之路(七):模块热替换HMR

article/2025/10/7 11:55:18

HMR

模块热替换(Hot Module Replacement 或 HMR)允许在运行时更新各种模块,而无需进行完全刷新。

HMR主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面时丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。

HMR 不适用于生产环境,这意味着它应当只在开发环境使用。


一、使用 HMR

这里,我们是基于上一节的webpack-dev-server的项目结构配置进行讲解的。

要开启HMR,我们只需要更新 webpack-dev-server 的配置 和 使用 webpack 内置的 HMR 插件 即可。

若你使用了 webpack-dev-middleware 而没有使用 webpack-dev-server,请使用 webpack-hot-middleware package 包,以在你的自定义服务或应用程序上启用 HMR。

(1)开启HMR
webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');   //+module.exports = {entry:{//删除了 print.js 的入口,因为它现在正被 index.js 模块使用。app: './src/index.js'       //+},devtool: 'inline-source-map',devServer: {contentBase: './dist',hot: true						//+},plugins: [new CleanWebpackPlugin(['dist']),new HtmlWebpackPlugin({title:'Output Management'}),new webpack.NamedModulesPlugin(),    //+new webpack.HotModuleReplacementPlugin() //+],output:{filename:'[name].bundle.js',path:path.resolve(__dirname,'dist'),publicPath: '/'}
}

这里我们还添加了 NamedModulesPlugin,以便更容易查看要修补(patch)的依赖。现在HMR已经开启!

(2)运行 npm start

(3)print.js 内部发生变化时,要可以告诉 webpack 接受更新的模块。
所以要修改 index.js.

src/index.js:

import printMe from './print.js';function component() {var element = document.createElement('div');element.innerHTML = 'Hello webpack';var oButton = document.createElement('button');oButton.innerHTML = 'click me and check console!';oButton.onclick = printMe;element.appendChild(oButton);return element;
}document.body.appendChild(component());if(module.hot) {										//+module.hot.accept('./print.js', function() {		//+console.log('Accepting the updated printMe module!'); //+printMe();										//+})													//+
}														//+

更改 print.js 中 console.log 的输出内容,
src/print.js:

export default function printMe() {console.log('Updating print.js...');
}

此时你会在浏览器控制台看到如下的输出:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、使用 HMR 2.0

回到上面的示例中。如果你继续点击示例页面上的按钮,你会发现控制台仍在打印这旧的 printMe 功能。

这是因为按钮的 onclick 事件仍然绑定在旧的 printMe 函数上。

为了让它与 HMR 正常工作,我们需要使用 module.hot.accept 更新绑定到新的 printMe 函数上:

src/index.js:

import printMe from './print.js';function component() {var element = document.createElement('div');element.innerHTML = 'Hello webpack';var oButton = document.createElement('button');oButton.innerHTML = 'click me and check console!';oButton.onclick = printMe;element.appendChild(oButton);return element;
}let element = component(); // 当 print.js 改变导致页面重新渲染时,重新获取渲染的元素
document.body.appendChild(element);if(module.hot) {										module.hot.accept('./print.js', function() {		console.log('Accepting the updated printMe module!'); document.body.removeChild(element);element = component(); // 重新渲染页面后,component 更新 click 事件处理document.body.appendChild(element);							})													
}														

现在便解决了上面的问题。


3、HMR 修改样式表

借助 style-loader的帮助,CSS 的模块热替换非常简单。当更新 CSS 依赖模块时,此 loader 在后台使用 module.hot.accept 来修补 < style> 标签。

(1)安装两个 loader :

> sudo npm install --save-dev style-loader css-loader

(2)webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');   module.exports = {entry:{app: './src/index.js'},devtool: 'inline-source-map',devServer: {contentBase: './dist',hot: true						},module: {rules: [{test: /\.css$/,use: ['style-loader', 'css-loader']}]},plugins: [new CleanWebpackPlugin(['dist']),new HtmlWebpackPlugin({title:'Output Management'}),new webpack.NamedModulesPlugin(),    new webpack.HotModuleReplacementPlugin() ],output:{filename:'[name].bundle.js',path:path.resolve(__dirname,'dist'),publicPath: '/'}
}

(3)在src目录下创建styles.css,并修改./src/index.js

src/styles.css:

body {background: blue;
}

src/index.js:

import printMe from './print.js';
import './styles.css';function component() {var element = document.createElement('div');element.innerHTML = 'Hello webpack';var oButton = document.createElement('button');oButton.innerHTML = 'click me and check console!';oButton.onclick = printMe;element.appendChild(oButton);return element;
}let element = component();
document.body.appendChild(element);if(module.hot) {										module.hot.accept('./print.js', function() {		console.log('Accepting the updated printMe module!'); document.body.removeChild(element);element = component();document.body.appendChild(element);							})													
}														

(4)修改src/styles.css,无需完全刷新,查看其变化:

src/styles.css:

body {background: red;
}

你发现页面的背景颜色自动变为红色。


其他代码和框架

还有许多其他 loader 和示例,可以使 HMR 与各种框架和库(library)平滑地进行交互:

  • React Hot Loader:实时调整 react 组件。
  • Vue Loader:此 loader 支持用于 vue 组件的 HMR,提供开箱即用体验。
  • Elm Hot Loader:支持用于 Elm 程序语言的 HMR。
  • Redux HMR:无需 loader 或插件!只需对 main store 文件进行简单的修改。
  • Angular HMR:No loader necessary! A simple change to your main - NgModule file is all that’s required to have full control over the HMR APIs.没有必要使用 loader!只需对主要的 NgModule 文件进行简单的修改,由 HMR API 完全控制。


http://chatgpt.dhexx.cn/article/Jl7rycXY.shtml

相关文章

【Webpack 性能优化系列(1) - HMR 热模块替换】

webpack系列文章&#xff1a; 【Webpack 性能优化系列(9) - 多进程打包】极大的提升项目打包构建速度&#xff01;&#xff01;&#xff01;【Webpack 性能优化系列(8) - PWA】使用渐进式网络应用程序为我们的项目添加离线体验【Webpack 性能优化系列(7) - 懒加载和预加载】【…

hmr webpack 不编译_Webpack HMR 热更新实现原理深入分析

概述 在使用 Webpack 构建开发期时&#xff0c;Webpack 提供热更新功能为开发带来良好的体验和开发效率&#xff0c;那热更新机制是怎么实现的呢&#xff1f; 代码实现 Webpack 配置添加 HotModuleReplacementPlugin 插件 new webpack.HotModuleReplacementPlugin({ // Options…

webpack4.0核心概念(十)—— HMR(热模块替换-局部刷新)

HMR&#xff1a;当修改一个js或者css的时候&#xff0c;只刷新修改的内容&#xff0c;不进行整个页面的刷新。 css的HMR——只支持开发环境 不能使用mini-css-extract-plugin需要使用style-loader,因为它不支持抽离出的css,需要用style-loader ① 在webpack.config.js中配置 …

前端工程化——Livereload和HMR、本地开发服务器

目录 本地开发服务器解决的问题 动态构建 Mock服务 动态构建 源码改动之后&#xff0c;浏览器应该在何时获取重新编译后的资源&#xff1f; Livereload和HMR 有了构建系统的支持&#xff0c;前端开发人员可以使用诸多有利于开发和维护的技术进行源代码编写。然而如果在开…

hmr webpack 不编译_webpack hmr

参考&#xff1a; hmr技术支持程序运行时的模块(amd、commonJS等)的修改、添加和删除&#xff0c;而不用整个程序重新加载&#xff0c;这可以提升开发的效率&#xff1a; hmr后程序的状态可以得到保存 仅仅改变变化的部分&#xff0c;其余不变 调样式更加快捷&#xff0c;基本比…

18.webpack4之HMR

1.HMR&#xff08;Hot Module Replacement&#xff09;热模块替换 在开发环境&#xff0c;可以使用热模块替换&#xff08;HMR&#xff09;去实现如果一个模块发生变化&#xff0c;只会重新打包这一个模块&#xff08;而不是所有模块都进行打包&#xff09;&#xff0c;而无需重…

webpack5之HMR原理探究

一、概念介绍 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块&#xff0c;而无需完全刷新。 主要是通过以下几种方式&#xff0c;来显著加快开发速度&#xff1a; 保留在完全重新加载页面期间丢失的应用程…

hmr webpack 不编译_一文搞懂 webpack HMR 原理

关注「前端向后」微信公众号&#xff0c;你将收获一系列「用心原创」的高质量技术文章&#xff0c;主题包括但不限于前端、Node.js以及服务端技术 一.HMR Hot Module Replacement(HMR)特性最早由 webpack 提供&#xff0c;能够对运行时的 JavaScript 模块进行热更新(无需重刷&a…

Webpack HMR 原理全解析

执行 npx webpack serve 命令后&#xff0c;WDS 调用 HotModuleReplacementPlugin 插件向应用的主 Chunk 注入一系列 HMR Runtime&#xff0c;包括&#xff1a; 用于建立 WebSocket 连接&#xff0c;处理 hash 等消息的运行时代码 用于加载热更新资源的 RuntimeGlobals.hmrDow…

vite1.x 热更新(HMR)的实现原理

前言 将近一年前自己尝试阅读vite源码&#xff08;2.x&#xff09;&#xff0c;虽然也有些收获但整体并没有到达我的预期&#xff0c;对于vite也是停留在一知半解的程度上。最近想重新开始学习vite&#xff0c;但回顾之前的学习历程&#xff0c;感觉不太想继续之前的方式&…

Webpack HMR 原理解析

Hot Module Replacement&#xff08;以下简称 HMR&#xff09;是 webpack 发展至今引入的最令人兴奋的特性之一 &#xff0c;当你对代码进行修改并保存后&#xff0c;webpack 将对代码重新打包&#xff0c;并将新的模块发送到浏览器端&#xff0c;浏览器通过新的模块替换老的模…

Webpack的HMR原理解析

Hot Module Replacement&#xff08;以下简称 HMR&#xff09;是 webpack 发展至今引入的最令人兴奋的特性之一 &#xff0c;当你对代码进行修改并保存后&#xff0c;webpack 将对代码重新打包&#xff0c;并将新的模块发送到浏览器端&#xff0c;浏览器通过新的模块替换老的模…

Esbuild Bundler HMR

Esbuild 虽然 bundler 非常快&#xff0c;但是其没有提供 HMR 的能力&#xff0c;在开发过程中只能采用 live-reload 的方案&#xff0c;一有代码改动&#xff0c;页面就需要全量 reload &#xff0c;这极大降低开发体验。为此添加 HMR 功能至关重要。 经过调研&#xff0c;社…

Vite HMR

传统webpack的hmr是使用webpack的HotModuleReplacementPlugin&#xff0c;而vite则是采用native ES Module的devServer。 初始化本地服务器加载并运行对应的plugin 最重要的一件事就是运行plugin&#xff0c;目前vite支持的plugin大体如下图所示 1、建立ViteDevServer服务器…

webpack HMR

HMR或者hot模式下&#xff0c;启动webpack会在浏览器与服务器之间会建立一个websocket连接&#xff0c;使得浏览器可以和服务端建立全双工通信&#xff1b;当应用程序的代码更新时&#xff0c;会要求HMR runtime检查更新&#xff0c;有更新时&#xff0c;在websoket连接中会返回…

webpack中的HMR(热更新)原理剖析

简介 Hot Module Replacement&#xff08;以下简称 HMR&#xff09;是 webpack 发展至今引入的最令人兴奋的特性之一 &#xff0c;当你对代码进行修改并保存后&#xff0c;webpack 将对代码重新打包&#xff0c;并将新的模块发送到浏览器端&#xff0c;浏览器通过新的模块替换…

HMR(热替换)

HMR 即模块热替换&#xff08;hot module replacement&#xff09;的简称&#xff0c;它可以在应用运行的时候&#xff0c;不需要刷新页面&#xff0c;就可以直接替换、增删模块。webpack 可以通过配置 webpack.HotModuleReplacementPlugin 插件来开启全局的 HMR 能力&#xff…

面试官:说说Webpack的热更新是如何做到的?原理是什么?

一、是什么 HMR全称 Hot Module Replacement&#xff0c;可以理解为模块热替换&#xff0c;指在应用程序运行过程中&#xff0c;替换、添加、删除模块&#xff0c;而无需重新刷新整个应用 例如&#xff0c;我们在应用运行过程中修改了某个模块&#xff0c;通过自动刷新会导致整…

Webpack 热更新HMR 原理全解析

一、什么是 HMR HMR 全称 Hot Module Replacement&#xff0c;中文语境通常翻译为模块热更新&#xff0c;它能够在保持页面状态的情况下动态替换资源模块&#xff0c;提供丝滑顺畅的 Web 页面开发体验。 HMR 最初由 Webpack 设计实现&#xff0c;至今已几乎成为现代工程化工具…

curl.perform() pycurl.error: (23, 'Failed writing body (0 != 59)')

在使用python3.7编码时&#xff0c;引入pycurl模块和StringIO模块后&#xff0c;容易引起上述错误 导入StringIO模块的解决方案&#xff1a; 只有在python2中才能导入StringIO模块&#xff0c;直接 from StringIO import StringIO 即可 但是python3&#xff0c;STringIO和…