gpt4 book ai didi

Webpack 子编译器更改配置

转载 作者:行者123 更新时间:2023-12-04 16:58:41 25 4
gpt4 key购买 nike

我希望我的 webpack 构建的输出在编译我的 service worker 时被定义为一个变量。

我想使用子编译功能来编译放入不同路径的服务 worker 。我需要从 webpack 编译发出的输出来正确编译 service worker。

我最初的做法是使用与创建子编译器的离线插件相同的策略,但我需要能够更改服务 worker 的输出路径。服务 worker 路径很重要,因为它定义了范围。

我想知道如何使用子编译器 API 来完成下面的工作,以防止我的构建产生这种副作用(并希望它能给我 webpack-dev-server 支持。

var webpack = require('webpack');

function ServiceWorkerPlugin(options) {
this.options = options;
}

ServiceWorkerPlugin.prototype.apply = function(compiler) {
compiler.plugin('emit', (compilation, callback) => {
const stats = compilation.getStats().toJson();
const child = webpack(this.options);

child.apply(
new webpack.DefinePlugin({
assets: stats.assets
})
);

child.run((err, swStats) => {
if (err) {
callback(err);
}
const swStatsJson = swStats.toJson();

if(swStatsJson.errors.length > 0) {
console.log(swStatsJson.errors);
}

if(swStatsJson.warnings.length > 0) {
console.log(swStatsJson.warnings);
}

callback();
});

module.exports = ServiceWorkerPlugin;

最佳答案

首先,您所描述的一切都在offline-plugin 中。实现,所以现在我将向您展示我是如何做到的。

当你需要使用子编译和 compilation.assets 时,webpack 中的一切都变得有点棘手。在里面。问题是必须在 complier.plugin('make') 上创建子编译。事件,但 compilation.assets仅在 compiler.plugin('emit') 上可用几乎在编译结束时触发的事件。

这是子编译实现的样板:

(注:代码在ES2015版本)

import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin';

export default class AwesomePlugin {
constructor() {
// Define compilation name and output name
this.childCompilerName = 'awesome-plugin-compilation';
this.outputFileName = 'custom-file.js';
// To make child compiler work, you have to have a entry in the file system
this.compilationEntry = 'entry-file.js';
}

apply(compiler) {
// Listen to `make` event
compiler.plugin('make', (compilation, callback) => {
// Creating child compiler with params
const childCompiler = compilation.createChildCompiler(this.childCompilerName, {
filename: this.outputFileName
});

// Everyone plugin does this, I don't know why
childCompiler.context = compiler.context;

// Add SingleEntryPlugin to make all this work
childCompiler.apply(new SingleEntryPlugin(compiler.context, this.compilationEntry, this.outputFileName));

// Needed for HMR. Even if your plugin don't support HMR,
// this code seems to be always needed just in case to prevent possible errors
childCompiler.plugin('compilation', (compilation) => {
if (compilation.cache) {
if (!compilation.cache[name]) {
compilation.cache[name] = {};
}

compilation.cache = compilation.cache[name];
}
});

// Run child compilation
childCompiler.runAsChild((err, entries, childCompilation) => {
callback(err);
});
});
}
}

这将使您的条目编译成单独的文件,您可以随意命名。接下来,您需要对 compilation.assets 进行一些骇人听闻的操作。在 'emit'事件:
compiler.plugin('emit', function(compilation, callback) {
// Get our output asset
const asset = compilation.assets[this.outputFileName];

// Delete delete our asset from output
delete compilation.assets[this.outputFileName];

// Collect all output assets
const assets = Object.keys(compilation.assets);

// Combine collected assets and child compilation output into new source.
// Note: `globalAssets` is global variable
let source = `
var globalAssets = ${ JSON.stringify(assets) }

${ asset.source() }
`;

// Add out asset back to the output
compilation.assets[this.outputFileName] = {
source() {
return source;
},
size() {
return Buffer.byteLength(source, 'utf8');
}
};
});

编辑:您可能可以在要插入 Assets 列表的条目中放置一些特殊位置。但请注意,如果您使用常规模板语法,那么 JS 加载器将无法解析您的文件。所以你可以放置这样的 __INSERT_WEBPACK_ASSETS_DATA__然后使用 String#replace用实际数据替换它。

基本上就是这样。现在您应该可以使用 compilation.assets 注入(inject)变量了进入您的子编译输出。请注意,在 offline-plugin ,我在创建时使用假编译名称,然后在 'emit' 上重命名它事件到真实的文件名。我不记得确切的原因,但我记得我有它们。因此,您可能需要自己尝试一下。

以下是此样板的完整代码(包含 'make''emit' 事件): https://gist.github.com/NekR/f85d297fe4f1ea3c168827b305c13844

关于Webpack 子编译器更改配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38276028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com