likes
comments
collection
share

webpack 完全指南:文件监听和热更新

作者站长头像
站长
· 阅读数 12

文件监听

我们每次在对项目进行修改后,都要手动跑 webpack 打包命令,是不是很烦?Webpack 就不能帮我们监听文件的变化,然后在文件发生修改时自动编译打包吗?

webpack 说:我可以啊!我可以通过轮询去检查文件的最后编辑时间是否发生变化,从而判断是否需要重新编译(文件监听的实现原理)。

webpack 中开启监听模式,有两种方式:

  • 启动 webpack 命令时,带上 --watch 参数。
  • 在配置 webpack.config.js 中设置 watch:true

--watch

可以在 package.json 中配置监听命令:

{
  // ...
  "scripts": {
    "watch": "webpack --watch"
  }
}

然后跑 npm run watch,webpack 就进入了监听模式

watch: true

webpack.config.js 中配置监听模式:

module.exports = {
  //...
  watch: true,
};

watchOptions

通过 watchOptions 可以定制 watch 模式的选项。

watchOptions.aggregateTimeout

当第一个文件更改,会在重新构建前增加延迟。也就是说,webpack 会将这段时间内进行的任何其他更改都缓存起来,最后在一次重新构建中完成。默认为 200 毫秒。

// webpack.config.js

module.exports = {
  //...
  watchOptions: {
    aggregateTimeout: 600,
  },
};

watchOptions.ignored

忽略一些不需要监听的庞大文件,比如 node_modules,可以优化性能。

// webpack.config.js

module.exports = {
  //...
  watchOptions: {
    ignored: /node_modules/,
  },
};

watchOptions.poll

指定轮询的时间间隔。

module.exports = {
  //...
  watchOptions: {
    poll: 1000, // 每秒检查一次变动
  },
};

文件监听的缺陷

虽然,开启 webpack 的文件监听后,可以在源码发生改变时,自动的重新构建出新的输出文件;但是,还是需要 手动刷新浏览器 才能看到更新内容。

那么,这个“痛点”有没有解决方案吗?webpack 的 热更新 奉上。

热更新

热更新可以让我们在文件发生修改后,不刷新浏览器,页面就能自动更新。

webpack 完全指南:文件监听和热更新

在了解热更新流程之前,有必要对一些名词进行了解:

  • bundle.js: 构建输出的文件。
  • Webapck Compiler: webpack 的编辑器,将 JS 源代码编译为 bundle.js。
  • HMR Server: 将热更新的文件传输给 HMT Runtime。
  • Bundle Server: 在浏览器中,可以以服务器的形式访问文件
  • HMR Runtime: 在打包阶段被注入浏览器的 bundle.js 中,使 bundle.js 和 Server 建起链接(Web Socket),在文件发生变化时,自动更新 bundle.js 中的 Code。

⬆️ 然后我们具体走一下流程,从上图可以看出 热更新的完整流程分为两个阶段:

  • 启动阶段:

    • 1、在文件系统中进行编译
    • 2、通过 Webpack Compiler 进行打包
    • A、将打包好的文件传输给 Bundle Server
    • B、启动服务,使浏览器以 Server 的形式访问 bundle.js
  • 文件更新阶段:

    • 1、文件系统中的内容发生变化
    • 2、通过 Webpack Compiler 进行打包
    • 3、将打包好的文件传输给 HMR Server,分析哪些代码发生了改变
    • 4、HMR Server(服务端) 将改变通知到 HMR Runtime(客户端)
    • 5、HMR Runtime 更新 bundle.js 中的代码

webpack-dev-server

webpack-dev-server 为我们提供了一个基本的 web server,并且具有 live reloading(热更新)功能。

webpack-dev-server 并不会输出文件,也就是说不会发生磁盘的 I/O 操作,它是将 bundle 文件保留在内存中,所以相比 watch 性能更优。

首先,安装一下 webpack.config.js

npm i webpack-dev-server -D

然后,我们修改一下 webpack.config.js

  • 只在开发环境需要用到 webpack.config.js,所以修改 mode: 'development'
  • 告知 dev server,将 dist 目录下的文件 serve1 到 localhost:8080 下。
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "index.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader",
      },
    ],
  },
+  mode: "development",
+  devServer: { static: "./dist" },
  performance: {
    hints: false,
    maxEntrypointSize: 512000,
    maxAssetSize: 512000,
  },
};

添加一个可以直接运行 dev server 的 script--open 表示每次构建完成后自动打开页面:

// package.json
{
  // ...
  "script": {
    // ...
    "dev": "webpack-dev-server --open"
  }
}

现在,在命令行中运行 npm run dev,我们会看到浏览器自动加载页面(默认在 http://localhost:8080/index),试试看!

webpack 系列

Footnotes

  1. 将资源作为 server 的可访问文件

转载自:https://juejin.cn/post/7029625287721615390
评论
请登录