首先,您所描述的一切都在offline-plugin
实施,所以现在我将向您展示我是如何做到的。
当你需要使用 webpack 时,一切都变得有点棘手儿童汇编 and compilation.assets
在里面。问题是儿童汇编必须创建于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);
});
});
}
}
这将使您的条目编译成单独的文件,您可以根据需要命名该文件。接下来,您需要进行一些 hacky 操作compilation.assets
on 'emit'
event:
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');
}
};
});
EDIT:您可能可以在要插入资产列表的条目中找到一些特殊的位置。但要小心,如果您使用常规模板语法,那么 JS 加载器将无法解析您的文件。所以你可以放置这样的东西__INSERT_WEBPACK_ASSETS_DATA__
然后使用String#replace
将其替换为实际数据。
基本上就是这样了。现在你应该能够注入变量compilation.assets
进入你的儿童汇编输出。请注意,在offline-plugin
, I use fake我创建它时的编译名称,然后将其重命名为'emit'
事件到真实的文件名。我不记得具体原因,但我记得我有它们。因此,您可能需要亲自尝试一下。
这是该样板的完整代码(同时包含'make'
and 'emit'
事件):https://gist.github.com/NekR/f85d297fe4f1ea3c168827b305c13844 https://gist.github.com/NekR/f85d297fe4f1ea3c168827b305c13844