我可以使用 webpack 钩子在保存之前修改文件输出吗?

Can I use a webpack hook to modify file output just before it gets saved?

我想对一个文件进行webpack和babel处理后的操作。有一个 emit 挂钩在保存新文件之前触发,但我看不到操纵文件内容的方法。所以我决定使用 afterEmit 钩子来读取刚刚写入的文件,修改它,然后将其写回:

    plugins: [
      new class OutputMonitor {
        apply(compiler) {
          compiler.hooks.afterEmit.tap('OutputMonitor', compilation => {
            if (compilation.emittedAssets.has('index.js')) {
              let contents = fs.readFileSync('./dist/web/index.js', 'utf-8');
              // Strip out dynamic import() so it doesn't generate warnings.
              contents = contents.replace(/import(?=\("tseuqer-yb")/, 'console.log');
              // Strip out large and large-alt timezone definitions from this build.
              contents = contents.replace(large, 'null');
              contents = contents.replace(largeAlt, 'null');
              fs.writeFileSync('./dist/web/index.js', contents);
            }
          });
        }
      }()
    ],

这样就可以完成工作了,但是还有更好的方法吗?

据我所知,您基本上是在用另一个字符串替换一些字符串。

如果你是 运行 webpack 5,我相信你可以使用 processAssets 钩子。

这是一个您可以根据自己的情况进行调整的示例:

const { Compilation, sources } = require('webpack');

class Replace {
  apply(compiler) {
    compiler.hooks.thisCompilation.tap('Replace', (compilation) => {
      compilation.hooks.processAssets.tap(
        {
          name: 'Replace',
          stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE,
        },
        () => {
          // get the file main.js
          const file = compilation.getAsset('main.js');
          // update main.js with new content
          compilation.updateAsset(
            'main.js',
            new sources.RawSource(file.source.source().replace('a', 'b'))
          );
        }
      );
    });
  }
}
module.exports = {
  entry: './wp.js',
  plugins: [new Replace()],
};