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

如何在Webpack 5中生成每个Chunk对应的源文件清单?

Webpack 5 生成Chunk与源文件映射清单方案

需求概述

在Webpack 5构建流程中,生成一份Chunk输出文件→对应源文件列表的映射清单,格式示例如下:

{
  "app.930.59370e27f67ee1c4d4b8.js": [
     "/src/components/Header.vue",
     "/src/utils/api.js"
  ],
  "vendor.123.abc.js": [
     "/node_modules/react/index.js",
     "/node_modules/react-dom/index.js"
  ]
}

要求直接在构建过程中获取类似sourcemap中sources字段的完整源文件信息,避免事后批量读取.map文件的低效方式。

已尝试的无效方案

  • webpack-assets-manifest/webpack-manifest-plugin:仅提供带哈希与不带哈希的文件路径映射,无法获取Chunk包含的源文件列表。
  • Webpack自带recordsPath配置:仅记录触发Chunk拆分的文件(含import()的文件及直接导入文件),源文件信息不完整。

可行解决方案

方案:自定义Webpack插件

通过Webpack的编译钩子,在构建输出前直接收集Chunk与源文件的映射关系,生成目标清单并加入构建产物。

插件代码实现

创建ChunkSourceManifestPlugin.js文件:

const path = require('path');

class ChunkSourceManifestPlugin {
  constructor(options = {}) {
    this.outputFile = options.outputFile || 'chunk-source-manifest.json';
    this.rootDir = options.rootDir || process.cwd(); // 项目根目录,用于路径转换
  }

  apply(compiler) {
    // 在emit阶段(即将输出文件到磁盘前)执行逻辑
    compiler.hooks.emit.tapAsync('ChunkSourceManifestPlugin', (compilation, callback) => {
      const manifest = {};

      // 遍历所有编译生成的Chunk
      compilation.chunks.forEach(chunk => {
        // 遍历当前Chunk对应的所有输出文件(仅处理JS文件)
        chunk.files.forEach(file => {
          if (!file.endsWith('.js')) return;

          // 收集当前Chunk包含的所有源文件路径
          const sourcePaths = [];
          chunk.modulesIterable.forEach(module => {
            // 跳过Webpack内部模块,仅处理有原始资源路径的模块
            if (module.resource) {
              // 转换为相对于项目根的路径,或保留绝对路径
              const relativePath = path.relative(this.rootDir, module.resource);
              // 如需绝对路径,替换为:const sourcePath = module.resource;
              sourcePaths.push(`/${relativePath}`);
            }
          });

          // 去重后存入清单(避免重复模块)
          if (sourcePaths.length) {
            manifest[file] = [...new Set(sourcePaths)];
          }
        });
      });

      // 将清单添加到构建输出资产中
      compilation.assets[this.outputFile] = {
        source: () => JSON.stringify(manifest, null, 2),
        size: () => Buffer.byteLength(JSON.stringify(manifest, null, 2), 'utf8')
      };

      callback();
    });
  }
}

module.exports = ChunkSourceManifestPlugin;

在Webpack配置中使用

修改webpack.config.js,引入并实例化插件:

const ChunkSourceManifestPlugin = require('./ChunkSourceManifestPlugin');

module.exports = {
  // ...其他Webpack配置项
  plugins: [
    // ...已有的插件
    new ChunkSourceManifestPlugin({
      outputFile: 'chunk-source-manifest.json', // 输出的清单文件名
      rootDir: __dirname // 你的项目根目录,用于路径转换
    })
  ]
};

关键说明

  1. 钩子选择:使用compiler.hooks.emit钩子,确保在文件输出前完成数据收集,避免额外的文件读写操作。
  2. 模块过滤:通过module.resource判断模块是否有原始源文件路径,可按需添加过滤规则(如排除node_modules中的依赖):
    // 示例:仅保留项目源码,排除node_modules依赖
    if (module.resource && !module.resource.includes('node_modules')) {
      // ...收集逻辑
    }
    
  3. 路径处理:通过path.relative将绝对路径转换为相对于项目根的短路径,也可直接保留绝对路径,根据需求调整。
  4. 异步Chunk支持:compilation.chunks包含所有类型的Chunk(同步、异步),无需额外处理即可覆盖动态导入的Chunk。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:44:58