美文网首页
webpack 之 hot module replacement

webpack 之 hot module replacement

作者: 在幽幽暗暗反反复复中追问 | 来源:发表于2020-06-20 20:11 被阅读0次

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:

  1. The application asks the HMR runtime to check for updates.
  2. The runtime asynchronously downloads the updates and notifies the application.
  3. The application then asks the runtime to apply the updates.
  4. The runtime synchronously applies the updates.

比如说,你在输入框中填入了信息,然后在源码中修改了输入框的 css,如果开启了热更替,那么 css 就马上生效了,且不会刷新页面,输入框中的信息没有变化(需要使用 style-loader HMR with Stylesheets
如果没有开启热更替,那么页面会刷新,你在输入框中输入的内容也因为刷新丢失了(需要设置 devServer 的 open 属性)

针对 css 模块配置 hot module replacement:

  1. 设置 hot: true
  2. hotOnly:这个配置项的意思是,即使 hot module replace 无效,也不要刷新页面
  3. 使用 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: truehotOnly 还需要

  1. 使用 webpack 提供的 HotModuleReplacementPlugin
  2. 使用 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.

相关文章

网友评论

      本文标题:webpack 之 hot module replacement

      本文链接:https://www.haomeiwen.com/subject/sqfetktx.html