Webpack 生成源映射时出现问题——仅在禁用特定插件时生成

Webpack problem generating sourcemaps -- only generated when a particular plugin is disabled

我正在使用自己的自定义插件从构建中删除一些可选代码。这很好用,但出于某种原因,它似乎阻止了源映射的生成。

我最好的猜测是我正在修改 index.js 输出文件这一事实干扰了为该文件生成地图的能力。如果我注释掉插件,我的源映射就会回来。

也许我可以做些什么来改变插件执行的顺序来解决这个问题?或者也许是一种从源文件输入流(而不是从文件本身)而不是从生成的输出中剥离代码的方法?

我已经尝试将 SourceMapDevToolPlugin 显式添加到我的插件中,但这没有帮助。

这是我的 webpack.config.cjs 文件:

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

module.exports = env => {
  const esVersion = env?.esver === '5' ? 'es5' : 'es6';
  const dir = env?.esver === '5' ? 'web5' : 'web';
  const chromeVersion = env?.esver === '5' ? '23' : '51';

  // noinspection JSUnresolvedVariable,JSUnresolvedFunction,JSUnresolvedFunction
  return {
    mode: env?.dev ? 'development' : 'production',
    target: [esVersion, 'web'],
    entry: {
      index: './dist/index.js'
    },
    output: {
      path: resolve(__dirname, 'dist/' + dir),
      filename: `index.js`,
      libraryTarget: 'umd',
      library: 'tbTime'
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          use: {
            loader: 'babel-loader',
            options: { presets: [['@babel/preset-env', { targets: { chrome: chromeVersion } }]] }
          },
          resolve: { fullySpecified: false }
        }
      ]
    },
    resolve: {
      mainFields: ['esm2015', 'es2015', 'module', 'main', 'browser']
    },
    externals: { 'by-request': 'by-request' },
    devtool: 'source-map',
    plugins: [
      new class OutputMonitor {
        // noinspection JSUnusedGlobalSymbols
        apply(compiler) {
          compiler.hooks.thisCompilation.tap('OutputMonitor', (compilation) => {
            compilation.hooks.processAssets.tap(
              { name: 'OutputMonitor', stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE },
              () => {
                const file = compilation.getAsset('index.js');
                let contents = file.source.source();
                // Strip out dynamic import() so it doesn't generate warnings.
                contents = contents.replace(/return import\(.*?\/\* webpackIgnore: true \*\/.*?tseuqer-yb.*?\.join\(''\)\)/s, 'return null');
                // Strip out large and large-alt timezone definitions from this build.
                contents = contents.replace(/\/\* trim-file-start \*\/.*?\/\* trim-file-end \*\//sg, 'null');
                compilation.updateAsset('index.js', new sources.RawSource(contents));
              }
            );
          });
        }
      }()
    ]
  };
};

可在此处找到完整的项目源代码:https://github.com/kshetline/tubular_time/tree/development

我认为使用 RawSource 会禁用源映射。 devtool 正确的应该是 SourceMapSource 所以这个想法看起来像下面这样:

const file = compilation.getAsset('index.js');

const {devtool} = compiler.options;

let contents = file.source.source();
const {map} = file.source.sourceAndMap();

// your replace work
// ...

compilation.updateAsset(
  'index.js', 
  devtool
    // for devtool we have to pass map file but this the original one
    // it would be wrong since you have already changed the content 
    ? new sources.SourceMapSource(contents, 'index.js', map)
    : new sources.RawSource(contents)
);