/* * 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;