hot module replacement (HMR): It allows all kinds of modules to be updated at runtime without the need for a full refresh.
注意,这个只在用在开发模式
In the Application
The following steps allow modules to be swapped in and out of an application:
- The application asks the HMR runtime to check for updates.
- The runtime asynchronously downloads the updates and notifies the application.
- The application then asks the runtime to apply the updates.
- The runtime synchronously applies the updates.
比如说,你在输入框中填入了信息,然后在源码中修改了输入框的 css,如果开启了热更替,那么 css 就马上生效了,且不会刷新页面,输入框中的信息没有变化(需要使用 style-loader HMR with Stylesheets)
如果没有开启热更替,那么页面会刷新,你在输入框中输入的内容也因为刷新丢失了(需要设置 devServer 的 open 属性)
针对 css 模块配置 hot module replacement:
- 设置
hot: true
-
hotOnly
:这个配置项的意思是,即使 hot module replace 无效,也不要刷新页面 - 使用
style-loader
// webpack.config.js
const path = require("path")
module.exports = {
mode: "development",
entry: {
main: "./src/index.js",
},
module: {
rules: {
test: "/\.css$/",
use: [
"style-loader",
"css-loader",
]
}
},
devServer: {
contentBase: path.resolve(__dirname, "dist"),
open: true,
hot: true,
hotOnly: true,
},
plugins: [],
}
针对 js 配置 HMR:
除了设置 hot: true
,hotOnly
还需要
- 使用 webpack 提供的 HotModuleReplacementPlugin
- 使用 module.hot.accept 处理文件变化
// webpack.config.js
const path = require("path")
const webpack = require("webpack")
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
module.exports = {
mode: "development",
entry: {
main: "./src/index.js",
},
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist")
},
devServer: {
contentBase: path.resolve(__dirname, "dist"),
open: true,
port: 9000,
hot: true,
hotOnly: true,
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
template: "./index.html"
}),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader",
// MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 2
},
},
"postcss-loader",
"stylus-loader",
]
},
],
},
}
// 在引入 utils 的 js 文件中添加如下代码
if (module.hot) {
module.hot.accept("./utils/index.js", function () {
console.log('hmr')
console.log(add([1,2,3,4], 15))
})
}
为什么我们平时使用 Vue,React,style-loader 等就不需要写类似 module.hot
的代码 ? 框架搭配的 loader 自己写了类似 module.hot 的代码,比如 vue-loader
If a module has no HMR handlers, the update bubbles up. This means that a single handler can update a complete module tree. If a single module from the tree is updated, the entire set of dependencies is reloaded.
网友评论