概述:
模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块,而无需完全刷新。
注意:
HMR 并不适用于生产环境,HMR 只应当用于开发环境。更多详细信息, 请查看 生产环境 指南。
启动 HMR:
- 将
webpackConfig.devServer中的hot选项设置为true即可开启模块的热更新:
const config = {
// ...
devServer: {
// ...
hot: true, // 把这里设置成 true
}
};
module.exports = config;
- 在
package.json命令行中添加--hot也可以开启模块的热更新
{
"dev": "webpack-dev-server --config ./webpack.config.js --hot"
}
提示:
- 从
webpack-dev-serverv4.0.0 开始,热模块替换是默认开启的。- 如果你在技术选型中使用了
webpack-dev-middleware而没有使用webpack-dev-server,请使用 webpack-hot-middleware 依赖包,以在你的自定义服务器或应用程序上启用 HMR。
为 HMR 提供入口:
步骤:
- 在
entry选项中添加 hot 入口和配置entry.devServer的client - 关闭
devServer选项中的client和hot - 在
plugins选项中HotMoudleRelacementPlugin
代码示例:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const config = {
entry: {
app: './src/index.js',
// =================================> 1
hot: 'webpack/hot/dev-server.js',
// =================================> 1
client: 'webpack-dev-server/client/index.js?hot=true&live-reload=true',
},
devtool: 'inline-source-map',
devServer: {
static: './dist',
// =================================> 2
hot: false,
// =================================> 2
client: false,
},
plugins: [
new HtmlWebpackPlugin({
title: 'Hot Module Replacement',
}),
// =================================> 3
new webpack.HotModuleReplacementPlugin(),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
module.exports = config;
直接配置 Node.js API
除了导出 webpackConfig 对象的创建方式,还可以直接使用 devServer 启动。
步骤:
具体步骤如下:
- 配置 webpack 的
config - 调用
webpack(config)生成compiler - 将
compiler作为第二个参数实例化webpackDevServer对象server(第一个参数就是 devServer 中的配置) server.start()启动服务
代码示例:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const webpackDevServer = require('webpack-dev-server');
// 1. 配置选项
const config = {
mode: 'development',
entry: [
// webpack 热更新的开发服务器入口 (需要引入一下)
'webpack/hot/dev-server.js',
// webpack-dev-server 客户端 API 的 chunk(需要引入一下)
'webpack-dev-server/client/index.js?hot=true&live-reload=true',
// 你自己项目的入口
'./src/index.js',
],
devtool: 'inline-source-map',
plugins: [
// 定义热模块更新的插件
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
title: 'Hot Module Replacement',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};
// 2. 创建 compiler
const compiler = webpack(config);
// 3. 创建服务器
// 必须要手动创建 hot 和 client 这两个选项,所以先定义成 false
const server = new webpackDevServer({ hot: false, client: false }, compiler);
// 4. 启动项目
(async () => {
await server.start();
console.log('dev server is running');
})();
使用 HMR 实时加载样式:
借助于 style-loader,使用模块热替换来加载 CSS 实际上极其简单。
此 loader 在幕后使用了 module.hot.accept,在 CSS 依赖模块更新之后,会将其 patch(补丁) 打到 <style> 标签中。
框架层面的 HMR:
社区还提供许多其他 loader 和示例,可以使 HMR 与各种框架和库平滑地进行交互……
- React Hot Loader: 实时调整
react组件。 - Vue Loader: 此
loader支持vue组件的HMR,提供开箱即用体验。 - Elm Hot webpack Loader: 支持
Elm编程语言的HMR。 - Angular HMR: 没有必要使用
loader!直接修改NgModule主文件就够了,它可以完全控制 HMR API。 - Svelte Loader: 此
loader开箱即用地支持Svelte组件的热更新。