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)
);
我正在使用自己的自定义插件从构建中删除一些可选代码。这很好用,但出于某种原因,它似乎阻止了源映射的生成。
我最好的猜测是我正在修改 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)
);