You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Webpack done钩子中区分首次构建与刷新并统计构建速度?

区分Webpack构建类型与Stats接口说明

一、如何区分首次构建/DevServer热更新

方案1:维护实例状态+热更新标识判断

在插件实例中记录首次构建状态,结合Webpack的hotUpdateChunk字段判断是否为热更新,同时区分生产构建与开发服务环境:

class BuildStatsWebpackPlugin {
  constructor(options) {
    this.options = options || {};
    this.isFirstDevBuild = true; // 标记DevServer首次构建
  }
  apply(compiler) {
    // 判定是否为DevServer环境
    const isDevServer = compiler.watchMode || !!compiler.options.devServer;

    compiler.hooks.done.tap({ name: 'BuildStatsWebpackPlugin' }, (stats) => {
      const startTime = stats.compilation.startTime;
      const endTime = stats.compilation.endTime;
      const speed = endTime - startTime;

      let buildType = '';
      if (!isDevServer) {
        // 生产环境build命令
        buildType = 'build-speed';
      } else {
        if (this.isFirstDevBuild) {
          // DevServer首次启动构建
          buildType = 'devServer-start-speed';
          this.isFirstDevBuild = false;
        } else {
          // 热更新判断:react-refresh触发的更新会存在hotUpdateChunk
          const isHotRefresh = !!stats.compilation.hotUpdateChunk;
          buildType = isHotRefresh ? 'devServer-refresh-speed' : 'devServer-start-speed';
        }
      }

      report({
        buildType,
        speed
      });
    });
  }
}

方案2:结合invalid钩子标记热更新

Webpack在文件变更触发重新编译前会触发invalid钩子,可以用它标记即将到来的是热更新:

class BuildStatsWebpackPlugin {
  constructor(options) {
    this.options = options || {};
    this.isFirstDevBuild = true;
    this.isHotRefresh = false;
  }
  apply(compiler) {
    const isDevServer = compiler.watchMode || !!compiler.options.devServer;

    // 文件变更时标记为热更新
    compiler.hooks.invalid.tap('BuildStatsWebpackPlugin', () => {
      this.isHotRefresh = true;
    });

    compiler.hooks.done.tap({ name: 'BuildStatsWebpackPlugin' }, (stats) => {
      const startTime = stats.compilation.startTime;
      const endTime = stats.compilation.endTime;
      const speed = endTime - startTime;

      let buildType = '';
      if (!isDevServer) {
        buildType = 'build-speed';
      } else {
        if (this.isFirstDevBuild) {
          buildType = 'devServer-start-speed';
          this.isFirstDevBuild = false;
        } else {
          buildType = this.isHotRefresh ? 'devServer-refresh-speed' : 'devServer-start-speed';
        }
      }

      report({
        buildType,
        speed
      });
      // 重置热更新标记
      this.isHotRefresh = false;
    });
  }
}

二、Webpack Stats接口说明

Webpack 5的Stats对象类型声明包含在webpack包中,核心属性如下:

  • stats.compilation.startTime: 编译开始的时间戳(数字类型)
  • stats.compilation.endTime: 编译结束的时间戳(数字类型)
  • stats.compilation.hotUpdateChunk: 热更新时生成的chunk名称(字符串或undefined,热更新时存在)
  • stats.compilation.name: 编译的自定义名称(部分插件会赋值)
  • stats.hasErrors(): 返回布尔值,判断编译是否存在错误
  • stats.toJson(): 将Stats转换为结构化JSON输出,可传入配置参数控制输出内容

如果是TypeScript项目,直接导入类型即可使用:

import type { Stats, Compilation } from 'webpack';

JavaScript项目可通过console.log(stats.compilation)打印完整结构,查看所有可用属性。

内容的提问来源于stack exchange,提问作者Deland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:46:33