Webpack 热模块替换(HMR)极简配置指南

作者:南风时间:2026-10-22 13:36:34浏览:405

本文介绍如何在不依赖 React 的情况下,配置 Webpack 实现最简化的热模块替换(HMR)。通过结合 webpack-dev-server 与 nodemon 监听配置文件变化,演示如何配置 package.json 和 webpack.config.js,实现代码修改后无需刷新页面即可更新模块,适用于单一状态树的应用场景。

Webpack HMR 配置简介

本文介绍一种无需 React 等框架支持的 Webpack 热模块替换(HMR)极简配置方案,通常也被称为热更新。

模块热替换(HMR)的核心功能是在应用运行期间,无需刷新整个页面即可动态替换、添加或删除特定模块。这种机制对于由单一状态树构成的应用尤为有效,因为这类应用中的组件通常是“哑”组件(相对于“智能”组件),在代码变更后,组件状态仍能准确反映应用的最新状态。

Webpack-dev-server 内置了“实时重载”(live reload)功能,会在文件变更时自动刷新页面。

项目目录结构

项目文件目录结构如下:

  1. app
    1. a.js
    2. component.js
    3. index.js
  2. node_modules
  3. package.json
  4. webpack.config.js

模块导入与热更新原理

在 component.js 中导入 a.js,而在 index.js 中导入 component.js。只要修改其中任意一个文件,即可触发热更新功能。

核心代码配置

最关键的部分在于 index.js 中包含以下代码,这是实现热更新所必需的:


if(module.hot){
  module.hot.accept(moduleId, callback);
}

package.json 配置详解

以下是 package.json 的配置内容:


{
 "name": "webpack-hmr",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
  "start": "nodemon --watch webpack.config.js --exec \"webpack-dev-server --env development\"",
  "build": "webpack --env production"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 "devDependencies": {
  "html-webpack-plugin": "^2.28.0",
  "nodemon": "^1.11.0",
  "webpack": "^2.2.1",
  "webpack-dev-server": "^2.4.1"
 }
}

从依赖列表可以看出,这是一个极其简单的配置。其中 nodemon 用于监听 webpack.config.js 文件的状态,一旦该文件发生变动,nodemon 会自动重新执行相关命令。

关于 html-webpack-plugin,在此配置中是可以省略的。具体配置细节请参考:https://www.npmjs.com/package/html-webpack-plugin 。

这里定义了两个命令:start 用于开发环境,build 用于生产环境。--watch 参数用于监听一个或多个文件,--exec 则是 nodemon 用来执行其他命令的标志。具体配置说明请参考:https://c9.io/remy/nodemon。

webpack.config.js 配置说明

接下来是 webpack.config.js 配置文件。既然在 package.json 的 scripts 中定义了两类命令,我们需要在配置文件中实现两种情况的处理(即 development 和 production,你也可以根据需要修改配置以只保留一种)。


const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');

const PATHS = {
 app: path.join(__dirname, 'app'),
 build: path.join(__dirname, 'build'),
};

const commonConfig={
 entry: {
  app: PATHS.app + '/index.js',
 },
 output: {
  path: PATHS.build,
  filename: '[name].js',
 },
 watch: true,
 plugins: [
  new HtmlWebpackPlugin({
   title: 'Webpack demo',
  }),
 ],
}

function developmentConfig(){
 const config ={
  devServer:{
   historyApiFallback:true, //404s fallback to ./index.html
   // hotOnly:true, 使用hotOnly和hot都可以
   hot: true,
   stats:'errors-only', //只在发生错误时输出
   // host:process.env.Host, 这里是undefined,参考的别人文章有这个
   // port:process.env.PORT, 这里是undefined,参考的别人文章有这个
   overlay:{ //当有编译错误或者警告的时候显示一个全屏overlay
    errors:true,
    warnings:true,
   }
  },
   plugins: [
   new webpack.HotModuleReplacementPlugin(),
   new webpack.NamedModulesPlugin(), // 更新组件时在控制台输出组件的路径而不是数字ID,用在开发模式
   // new webpack.HashedModuleIdsPlugin(), // 用在生产模式
  ],
 };
 return Object.assign( 
  {},
  commonConfig,
  config,
  {
   plugins: commonConfig.plugins.concat(config.plugins),
  }
 );
}

module.exports = function(env){
 console.log("env",env);
 if(env=='development'){
  return developmentConfig();
 }
 return commonConfig;
};

关于 Object.assign,其第一个参数为目标对象。如果目标对象中的属性具有相同的键,则该属性将被源对象中的属性覆盖。后续的源属性会类似地覆盖先前的属性。这是一种浅赋值操作,对于对象的复制使用 = 号,即引用复制。

env 参数通过命令行接口(CLI)传入。

运行与测试

然后打开命令行进入当前目录,运行 npm start 或 npm run build 即可。需要注意的是,前者仅在开发环境下运行,不会输出文件(文件存在于内存中),只有运行后者才会生成实际的输出文件。

Demo 代码位于:https://github.com/yuwanlin/webpackHMR

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章