|
|
|
/*
|
|
|
|
* worker-plugin
|
|
|
|
*/
|
|
|
|
|
|
|
|
const path = require('path');
|
|
|
|
const webpack = require('webpack');
|
|
|
|
const { WorkerPluginName } = require('./constants');
|
|
|
|
const ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers');
|
|
|
|
|
|
|
|
class FuiWorkerPlugin {
|
|
|
|
constructor(options = {}) {
|
|
|
|
this.options = options;
|
|
|
|
}
|
|
|
|
|
|
|
|
apply(compiler) {
|
|
|
|
// 为主线程构建添加 __WORKER__ 环境变量, 构建中区分不同线程源码, 实现代码拆减
|
|
|
|
compiler.hooks.afterPlugins.tap(WorkerPluginName, compiler => {
|
|
|
|
new webpack.DefinePlugin({
|
|
|
|
// __WORKER__ 表示当前所在线程是否是 worker 线程
|
|
|
|
// 主线程构建中为 false
|
|
|
|
__WORKER__: false,
|
|
|
|
}).apply(compiler);
|
|
|
|
});
|
|
|
|
|
|
|
|
// 添加自定义的worker entry-loader
|
|
|
|
compiler.hooks.afterResolvers.tap(WorkerPluginName, compiler => {
|
|
|
|
/**
|
|
|
|
* https://webpack.js.org/configuration/resolve/#resolveloader
|
|
|
|
* 使用 resolveloader 添加自定义的 worker loader
|
|
|
|
*/
|
|
|
|
if (!compiler.options.resolveLoader) {
|
|
|
|
compiler.options.resolveLoader = {
|
|
|
|
alias: {},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (!compiler.options.resolveLoader.alias) {
|
|
|
|
compiler.options.resolveLoader.alias = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
// 动态添加 worker 的 worker-loader, 命名为 "fui-worker"
|
|
|
|
compiler.options.resolveLoader.alias['fui-worker'] = path.resolve(__dirname, './worker-loader.js');
|
|
|
|
});
|
|
|
|
|
|
|
|
// 将FuiWorkerPlugin的参数传递给fui-worker loader
|
|
|
|
compiler.hooks.compilation.tap(WorkerPluginName, compilation => {
|
|
|
|
compilation.hooks.normalModuleLoader.tap(WorkerPluginName, (context, module) => {
|
|
|
|
// 仅提供给fui-worker
|
|
|
|
const fuiLoader = module.loaders.find(loader => loader.loader.indexOf('fui-worker') !== -1);
|
|
|
|
|
|
|
|
if (fuiLoader) {
|
|
|
|
const resource = module.resource;
|
|
|
|
|
|
|
|
if (!resource) return;
|
|
|
|
|
|
|
|
// fui-worker通过options读取
|
|
|
|
context.options = context.options || {};
|
|
|
|
|
|
|
|
const index = resource.indexOf('?');
|
|
|
|
|
|
|
|
if (ModuleFilenameHelpers.matchObject(
|
|
|
|
this.options,
|
|
|
|
index < 0 ? resource : resource.substr(0, index)
|
|
|
|
)) {
|
|
|
|
for (const key of Object.keys(this.options)) {
|
|
|
|
// 忽略关键属性
|
|
|
|
if (key === "include" || key === "exclude" || key === "test") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
context.options[key] = this.options[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = FuiWorkerPlugin;
|