@tarojs/webpack5-runner 4.2.1 → 4.2.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/index.mini.js +15 -4
  2. package/dist/index.mini.js.map +1 -1
  3. package/dist/plugins/AsyncSubPackagePlugin.js +489 -0
  4. package/dist/plugins/AsyncSubPackagePlugin.js.map +1 -0
  5. package/dist/plugins/BuildNativePlugin.js +22 -11
  6. package/dist/plugins/BuildNativePlugin.js.map +1 -1
  7. package/dist/plugins/HarmonyPlugin.js +1 -1
  8. package/dist/plugins/HarmonyPlugin.js.map +1 -1
  9. package/dist/plugins/MiniCompileModePlugin.js +49 -4
  10. package/dist/plugins/MiniCompileModePlugin.js.map +1 -1
  11. package/dist/plugins/MiniPlugin.js +282 -58
  12. package/dist/plugins/MiniPlugin.js.map +1 -1
  13. package/dist/plugins/SubPackageIndiePlugin.js +1060 -0
  14. package/dist/plugins/SubPackageIndiePlugin.js.map +1 -0
  15. package/dist/plugins/TaroInjectSyncCorePlugin.js +39 -0
  16. package/dist/plugins/TaroInjectSyncCorePlugin.js.map +1 -0
  17. package/dist/plugins/TaroNormalModule.js +16 -0
  18. package/dist/plugins/TaroNormalModule.js.map +1 -1
  19. package/dist/plugins/TaroNormalModulesPlugin.js +127 -6
  20. package/dist/plugins/TaroNormalModulesPlugin.js.map +1 -1
  21. package/dist/plugins/TaroSingleEntryPlugin.js +1 -1
  22. package/dist/plugins/TaroSingleEntryPlugin.js.map +1 -1
  23. package/dist/shared-runtime/app-shim.js +305 -0
  24. package/dist/shared-runtime/async-provider.js +144 -0
  25. package/dist/shared-runtime/build-shared-runtime.js +377 -0
  26. package/dist/shared-runtime/build-shared-runtime.js.map +1 -0
  27. package/dist/shared-runtime/constants.js +50 -0
  28. package/dist/shared-runtime/constants.js.map +1 -0
  29. package/dist/shared-runtime/entry.sync.js +102 -0
  30. package/dist/shared-runtime/externals.js +96 -0
  31. package/dist/shared-runtime/externals.js.map +1 -0
  32. package/dist/shared-runtime/scan-imperative-api.js +267 -0
  33. package/dist/shared-runtime/scan-imperative-api.js.map +1 -0
  34. package/dist/template/comp.js +2 -1
  35. package/dist/utils/asyncSubPackage.js +106 -0
  36. package/dist/utils/asyncSubPackage.js.map +1 -0
  37. package/dist/utils/component.js +2 -1
  38. package/dist/utils/component.js.map +1 -1
  39. package/dist/utils/forceCustomWrapper.js +17 -0
  40. package/dist/utils/forceCustomWrapper.js.map +1 -0
  41. package/dist/utils/webpack.js +40 -1
  42. package/dist/utils/webpack.js.map +1 -1
  43. package/dist/webpack/HarmonyWebpackPlugin.js +3 -1
  44. package/dist/webpack/HarmonyWebpackPlugin.js.map +1 -1
  45. package/dist/webpack/MiniBaseConfig.js +2 -0
  46. package/dist/webpack/MiniBaseConfig.js.map +1 -1
  47. package/dist/webpack/MiniCombination.js +51 -26
  48. package/dist/webpack/MiniCombination.js.map +1 -1
  49. package/dist/webpack/MiniWebpackPlugin.js +17 -1
  50. package/dist/webpack/MiniWebpackPlugin.js.map +1 -1
  51. package/package.json +14 -13
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12,21 +35,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
36
  };
14
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.STYLE_ISOLATION_SHARED = exports.STYLE_ISOLATION_APPLY_SHARED = exports.customWrapperName = exports.baseCompName = void 0;
15
39
  const node_path_1 = __importDefault(require("node:path"));
16
40
  const helper_1 = require("@tarojs/helper");
17
41
  const loader_utils_1 = require("loader-utils");
42
+ const tapable_1 = require("tapable");
18
43
  const EntryDependency_1 = __importDefault(require("webpack/lib/dependencies/EntryDependency"));
19
44
  const TaroSingleEntryDependency_1 = __importDefault(require("../dependencies/TaroSingleEntryDependency"));
20
45
  const prerender_1 = require("../prerender/prerender");
46
+ const constants_1 = require("../shared-runtime/constants");
21
47
  const component_1 = require("../utils/component");
48
+ const forceCustomWrapper_1 = require("../utils/forceCustomWrapper");
22
49
  const webpack_1 = require("../utils/webpack");
50
+ const AsyncSubPackagePlugin_1 = __importDefault(require("./AsyncSubPackagePlugin"));
51
+ const SubPackageIndiePlugin_1 = __importStar(require("./SubPackageIndiePlugin"));
23
52
  const TaroLoadChunksPlugin_1 = __importDefault(require("./TaroLoadChunksPlugin"));
24
53
  const TaroNormalModulesPlugin_1 = __importDefault(require("./TaroNormalModulesPlugin"));
25
54
  const TaroSingleEntryPlugin_1 = __importDefault(require("./TaroSingleEntryPlugin"));
26
- const baseCompName = 'comp';
27
- const customWrapperName = 'custom-wrapper';
55
+ exports.baseCompName = 'comp';
56
+ exports.customWrapperName = 'custom-wrapper';
28
57
  const PLUGIN_NAME = 'TaroMiniPlugin';
29
58
  const CHILD_COMPILER_TAG = 'child';
59
+ exports.STYLE_ISOLATION_APPLY_SHARED = 'apply-shared';
60
+ exports.STYLE_ISOLATION_SHARED = 'shared';
30
61
  function isLoaderExist(loaders, loaderName) {
31
62
  return loaders.some(item => item.loader === loaderName);
32
63
  }
@@ -46,6 +77,9 @@ class TaroMiniPlugin {
46
77
  this.dependencies = new Map();
47
78
  this.pageLoaderName = '@tarojs/taro-loader/lib/page';
48
79
  this.independentPackages = new Map();
80
+ this.asyncSubPackagePlugin = null;
81
+ this.subPackageIndiePlugin = null;
82
+ this.forceCustomWrapperDefineDefinitions = null;
49
83
  const { combination } = options;
50
84
  const miniBuildConfig = combination.config;
51
85
  const { template, baseLevel = 16, experimental } = miniBuildConfig;
@@ -69,6 +103,22 @@ class TaroMiniPlugin {
69
103
  hot: options.hot,
70
104
  loaderMeta: options.loaderMeta || {},
71
105
  };
106
+ // 初始化扩展钩子
107
+ this.hooks = {
108
+ modifyEntries: new tapable_1.SyncWaterfallHook(['entries']),
109
+ modifyChunkRequire: new tapable_1.SyncWaterfallHook(['result', 'chunkId', 'miniType']),
110
+ afterResolveModule: new tapable_1.SyncHook(['resolveData']),
111
+ compileExtraEntries: new tapable_1.SyncHook(['compiler', 'compilation', 'promises']),
112
+ modifySkipRootTemplates: new tapable_1.SyncWaterfallHook(['skip']),
113
+ generateExtraFiles: new tapable_1.SyncWaterfallHook(['customWrapperRoots', 'compilation', 'compiler']),
114
+ modifyPageConfig: new tapable_1.SyncWaterfallHook(['context', 'page', 'customWrapperRoots']),
115
+ modifyComponentConfig: new tapable_1.SyncHook(['context', 'customWrapperRoots']),
116
+ afterGenerateFiles: new tapable_1.SyncHook(['compilation', 'compiler']),
117
+ optimizeAssets: new tapable_1.SyncHook(['compilation']),
118
+ modifyConfig: new tapable_1.SyncWaterfallHook(['config', 'componentName']),
119
+ modifyStyleImport: new tapable_1.SyncWaterfallHook(['context', 'page']),
120
+ modifyShouldProcessStyles: new tapable_1.SyncWaterfallHook(['shouldProcess']),
121
+ };
72
122
  if (template.isSupportRecursive === false && baseLevel > 0) {
73
123
  template.baseLevel = baseLevel;
74
124
  }
@@ -99,11 +149,20 @@ class TaroMiniPlugin {
99
149
  apply(compiler) {
100
150
  this.context = compiler.context;
101
151
  this.appEntry = this.getAppEntry(compiler);
152
+ if (this.options.newBlended) {
153
+ this.subPackageIndiePlugin = new SubPackageIndiePlugin_1.default(this);
154
+ this.subPackageIndiePlugin.apply();
155
+ // 反向挂到 combination,供主构建结束后的 buildSharedRuntime 读取 mainPackageRoots
156
+ // (把同步核 taro-shared-sync.js 拷进每个 mainPackageRoot,实现 subPackageIndie 自包含)。
157
+ this.options.combination.subPackageIndiePlugin = this.subPackageIndiePlugin;
158
+ }
102
159
  const { commonChunks, combination, framework, isBuildPlugin, newBlended, } = this.options;
103
160
  const { addChunkPages, onCompilerMake, modifyBuildAssets, onParseCreateElement, } = combination.config;
104
161
  /** build mode */
105
162
  compiler.hooks.run.tapAsync(PLUGIN_NAME, this.tryAsync((compiler) => __awaiter(this, void 0, void 0, function* () {
106
163
  yield this.run(compiler);
164
+ this.applyForceCustomWrapperDefine(compiler);
165
+ this.applyAsyncSubPackagePlugin(compiler);
107
166
  new TaroLoadChunksPlugin_1.default({
108
167
  commonChunks: commonChunks,
109
168
  isBuildPlugin,
@@ -120,6 +179,8 @@ class TaroMiniPlugin {
120
179
  this.isWatch = true;
121
180
  }
122
181
  yield this.run(compiler);
182
+ this.applyForceCustomWrapperDefine(compiler);
183
+ this.applyAsyncSubPackagePlugin(compiler);
123
184
  if (!this.loadChunksPlugin) {
124
185
  this.loadChunksPlugin = new TaroLoadChunksPlugin_1.default({
125
186
  commonChunks: commonChunks,
@@ -137,6 +198,7 @@ class TaroMiniPlugin {
137
198
  const dependencies = this.dependencies;
138
199
  const promises = [];
139
200
  this.compileIndependentPages(compiler, compilation, dependencies, promises);
201
+ this.hooks.compileExtraEntries.call(compiler, compilation, promises);
140
202
  dependencies.forEach(dep => {
141
203
  promises.push(new Promise((resolve, reject) => {
142
204
  compilation.addEntry(this.options.sourceDir, dep, Object.assign({ name: dep.name }, dep.options), err => err ? reject(err) : resolve(null));
@@ -149,12 +211,26 @@ class TaroMiniPlugin {
149
211
  /** For Webpack compilation get factory from compilation.dependencyFactories by denpendence's constructor */
150
212
  compilation.dependencyFactories.set(EntryDependency_1.default, normalModuleFactory);
151
213
  compilation.dependencyFactories.set(TaroSingleEntryDependency_1.default, normalModuleFactory);
214
+ if (this.options.newBlended) {
215
+ normalModuleFactory.hooks.afterResolve.tap(PLUGIN_NAME, (resolveData) => {
216
+ this.hooks.afterResolveModule.call(resolveData);
217
+ });
218
+ }
152
219
  /**
153
220
  * webpack NormalModule 在 runLoaders 真正解析资源的前一刻,
154
221
  * 往 NormalModule.loaders 中插入对应的 Taro Loader
155
222
  */
156
223
  compiler.webpack.NormalModule.getCompilationHooks(compilation).loader.tap(PLUGIN_NAME, (_loaderContext, module) => {
224
+ var _a;
157
225
  const { framework, loaderMeta, pxTransformConfig } = this.options;
226
+ // 共享运行时(split 模式):把 sharedRuntime 开关、pkgId(取 output.chunkLoadingGlobal,
227
+ // 每业务包已必须唯一)、全局对象键名(constants.ts 单一来源)透传给 app/page loader,
228
+ // 供产物注入多包 App 隔离逻辑。
229
+ const sharedRuntime = !!this.options.combination.config.sharedRuntime;
230
+ const sharedRuntimePkgId = sharedRuntime
231
+ ? ((_a = compiler.options.output) === null || _a === void 0 ? void 0 : _a.chunkLoadingGlobal) || 'webpackJsonp'
232
+ : undefined;
233
+ const sharedRuntimeGlobalKey = sharedRuntime ? constants_1.SHARED_GLOBAL_ASYNC : undefined;
158
234
  if (module.miniType === helper_1.META_TYPE.ENTRY) {
159
235
  const loaderName = '@tarojs/taro-loader';
160
236
  if (!isLoaderExist(module.loaders, loaderName)) {
@@ -169,7 +245,10 @@ class TaroMiniPlugin {
169
245
  behaviorsName: this.options.behaviorsName,
170
246
  blended: this.options.blended,
171
247
  newBlended: this.options.newBlended,
172
- pxTransformConfig
248
+ pxTransformConfig,
249
+ sharedRuntime,
250
+ sharedRuntimePkgId,
251
+ sharedRuntimeGlobalKey,
173
252
  }
174
253
  });
175
254
  }
@@ -200,7 +279,10 @@ class TaroMiniPlugin {
200
279
  appConfig: this.appConfig,
201
280
  runtimePath: this.options.runtimePath,
202
281
  behaviorsName: this.options.behaviorsName,
203
- hot: this.options.hot
282
+ hot: this.options.hot,
283
+ sharedRuntime,
284
+ sharedRuntimePkgId,
285
+ sharedRuntimeGlobalKey,
204
286
  }
205
287
  });
206
288
  }
@@ -292,6 +374,10 @@ class TaroMiniPlugin {
292
374
  let source;
293
375
  const id = (0, webpack_1.getChunkIdOrName)(chunk);
294
376
  const { miniType } = entryModule;
377
+ const modifyResult = this.hooks.modifyChunkRequire.call({ source: modules, handled: false }, id, miniType);
378
+ if (modifyResult === null || modifyResult === void 0 ? void 0 : modifyResult.handled) {
379
+ return modifyResult.source;
380
+ }
295
381
  const entryChunk = [{ name: 'app' }];
296
382
  // 所有模块都依赖app.js,确保@tarojs\plugin-platform-xxx\dist\runtime.js先于@tarojs/runtime执行,避免Taro API未被初始化
297
383
  if (this.nativeComponents.has(id) || miniType === helper_1.META_TYPE.STATIC) {
@@ -300,7 +386,8 @@ class TaroMiniPlugin {
300
386
  source = (0, webpack_1.addRequireToSource)(id, modules, v);
301
387
  }
302
388
  });
303
- return source;
389
+ // 如果没有依赖需要注入,返回原始模块
390
+ return source || modules;
304
391
  }
305
392
  else if (miniType === helper_1.META_TYPE.PAGE) {
306
393
  return (0, webpack_1.addRequireToSource)(id, modules, entryChunk);
@@ -309,6 +396,23 @@ class TaroMiniPlugin {
309
396
  });
310
397
  });
311
398
  }
399
+ /**
400
+ * 初始化异步分包插件。
401
+ * MiniPlugin 仅作为桥接,具体的 babel 注入、chunk 处理和 app.json 注册由 AsyncSubPackagePlugin 承担。
402
+ */
403
+ applyAsyncSubPackagePlugin(compiler) {
404
+ if (!this.subPackageIndiePlugin)
405
+ return;
406
+ const asyncRootMap = this.subPackageIndiePlugin.getAsyncSubPackageRootMap();
407
+ if (asyncRootMap.size === 0)
408
+ return;
409
+ if (!this.asyncSubPackagePlugin) {
410
+ this.asyncSubPackagePlugin = new AsyncSubPackagePlugin_1.default(this);
411
+ }
412
+ this.asyncSubPackagePlugin.updateAsyncRootMap(asyncRootMap);
413
+ this.asyncSubPackagePlugin.updateAsyncRuntimeRoots(this.subPackageIndiePlugin.getAsyncSubPackageRuntimeRoots());
414
+ this.asyncSubPackagePlugin.apply(compiler);
415
+ }
312
416
  /**
313
417
  * 根据 webpack entry 配置获取入口文件路径
314
418
  * @returns app 入口文件路径
@@ -354,6 +458,8 @@ class TaroMiniPlugin {
354
458
  */
355
459
  run(compiler) {
356
460
  return __awaiter(this, void 0, void 0, function* () {
461
+ var _a;
462
+ (_a = this.subPackageIndiePlugin) === null || _a === void 0 ? void 0 : _a.invalidateRunCache();
357
463
  if (this.options.isBuildPlugin) {
358
464
  this.getPluginFiles();
359
465
  this.getConfigFiles(compiler);
@@ -479,12 +585,12 @@ class TaroMiniPlugin {
479
585
  }
480
586
  if (!this.options.template.isSupportRecursive) {
481
587
  pluginJSON.publicComponents = Object.assign({}, publicComponents, {
482
- [baseCompName]: baseCompName
588
+ [exports.baseCompName]: exports.baseCompName
483
589
  });
484
590
  }
485
591
  if (isUsingCustomWrapper) {
486
592
  pluginJSON.publicComponents = Object.assign({}, publicComponents, {
487
- [customWrapperName]: customWrapperName
593
+ [exports.customWrapperName]: exports.customWrapperName
488
594
  });
489
595
  }
490
596
  }
@@ -613,8 +719,11 @@ class TaroMiniPlugin {
613
719
  */
614
720
  addEntry(entryPath, entryName, entryType, options = {}) {
615
721
  let dep;
616
- if (this.dependencies.has(entryPath)) {
617
- dep = this.dependencies.get(entryPath);
722
+ // 对于 STATIC 类型(如 comp/custom-wrapper),使用 entryName 作为 key 的一部分
723
+ // 这允许同一个模板文件被多次添加为不同名称的入口
724
+ const depKey = entryType === helper_1.META_TYPE.STATIC ? `${entryPath}#${entryName}` : entryPath;
725
+ if (this.dependencies.has(depKey)) {
726
+ dep = this.dependencies.get(depKey);
618
727
  dep.name = entryName;
619
728
  dep.loc = { name: entryName };
620
729
  dep.request = entryPath;
@@ -625,7 +734,7 @@ class TaroMiniPlugin {
625
734
  else {
626
735
  dep = new TaroSingleEntryDependency_1.default(entryPath, entryName, { name: entryName }, entryType, options);
627
736
  }
628
- this.dependencies.set(entryPath, dep);
737
+ this.dependencies.set(depKey, dep);
629
738
  }
630
739
  /**
631
740
  * 在 this.dependencies 中新增或修改 app、模板组件、页面、组件等资源模块
@@ -633,10 +742,17 @@ class TaroMiniPlugin {
633
742
  addEntries() {
634
743
  const { template } = this.options;
635
744
  this.addEntry(this.appEntry, 'app', helper_1.META_TYPE.ENTRY);
636
- if (!template.isSupportRecursive) {
745
+ const entryFlags = this.hooks.modifyEntries.call({
746
+ skipRootComp: false,
747
+ skipRootWrapper: false,
748
+ });
749
+ if (!template.isSupportRecursive && !entryFlags.skipRootComp) {
637
750
  this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/comp'), 'comp', helper_1.META_TYPE.STATIC);
638
751
  }
639
- this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
752
+ if (!entryFlags.skipRootWrapper) {
753
+ this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
754
+ }
755
+ // subPackageIndie 下的 comp/custom-wrapper 统一走独立子编译器,避免被主编译的公共 chunk 共享
640
756
  this.pages.forEach(item => {
641
757
  if (item.isNative) {
642
758
  this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
@@ -666,6 +782,39 @@ class TaroMiniPlugin {
666
782
  }
667
783
  });
668
784
  }
785
+ computeForceCustomWrapperForWebpackMainComp() {
786
+ var _a;
787
+ if (this.options.template.isSupportRecursive)
788
+ return false;
789
+ const independentPaths = new Set();
790
+ this.independentPackages.forEach(({ pages }) => {
791
+ pages.forEach(p => independentPaths.add(p));
792
+ });
793
+ for (const page of this.pages) {
794
+ if (page.isNative || independentPaths.has(page.path))
795
+ continue;
796
+ const content = (_a = this.filesConfig[this.getConfigFilePath(page.name)]) === null || _a === void 0 ? void 0 : _a.content;
797
+ if (content === null || content === void 0 ? void 0 : content.forceCustomWrapper)
798
+ return true;
799
+ }
800
+ return false;
801
+ }
802
+ computeForceCustomWrapperForIndieRoot(pages) {
803
+ return (0, forceCustomWrapper_1.computeForceCustomWrapperForIndependentPackage)(pages, this.pages, this.filesConfig, (p) => this.getConfigFilePath(p));
804
+ }
805
+ applyForceCustomWrapperDefine(compiler) {
806
+ if (this.options.template.isSupportRecursive)
807
+ return;
808
+ const value = JSON.stringify(this.computeForceCustomWrapperForWebpackMainComp());
809
+ if (!this.forceCustomWrapperDefineDefinitions) {
810
+ this.forceCustomWrapperDefineDefinitions = {
811
+ TARO_FORCE_CUSTOM_WRAPPER: value
812
+ };
813
+ new compiler.webpack.DefinePlugin(this.forceCustomWrapperDefineDefinitions).apply(compiler);
814
+ return;
815
+ }
816
+ this.forceCustomWrapperDefineDefinitions.TARO_FORCE_CUSTOM_WRAPPER = value;
817
+ }
669
818
  replaceExt(file, ext) {
670
819
  return node_path_1.default.join(node_path_1.default.dirname(file), node_path_1.default.basename(file, node_path_1.default.extname(file)) + `${ext}`);
671
820
  }
@@ -825,7 +974,7 @@ class TaroMiniPlugin {
825
974
  filename: `[name]${this.options.fileType.style}`,
826
975
  chunkFilename: `[name]${this.options.fileType.style}`
827
976
  }).apply(childCompiler);
828
- new compiler.webpack.DefinePlugin(this.options.constantsReplaceList).apply(childCompiler);
977
+ new compiler.webpack.DefinePlugin(Object.assign(Object.assign({}, this.options.constantsReplaceList), { TARO_FORCE_CUSTOM_WRAPPER: JSON.stringify(this.computeForceCustomWrapperForIndieRoot(pages)) })).apply(childCompiler);
829
978
  if (compiler.options.optimization) {
830
979
  new SplitChunksPlugin({
831
980
  chunks: 'all',
@@ -965,6 +1114,12 @@ class TaroMiniPlugin {
965
1114
  usingComponents[key] = match ? `${node_path_1.default.sep}${match[0]}` : compPath;
966
1115
  }
967
1116
  }
1117
+ cloneThirdPartyComponent(thirdPartyComponents, componentName) {
1118
+ const attrs = component_1.componentConfig.thirdPartyComponents.get(componentName);
1119
+ if (!attrs || thirdPartyComponents.has(componentName))
1120
+ return;
1121
+ thirdPartyComponents.set(componentName, new Set(attrs));
1122
+ }
968
1123
  /** 生成小程序独立分包的相关文件 */
969
1124
  generateIndependentMiniFiles(compilation, compiler) {
970
1125
  return __awaiter(this, void 0, void 0, function* () {
@@ -981,24 +1136,27 @@ class TaroMiniPlugin {
981
1136
  this.generateTemplateFile(compilation, compiler, `${name}/${baseTemplateName}`, template.buildTemplate, component_1.componentConfig);
982
1137
  if (!template.isSupportRecursive) {
983
1138
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
984
- this.generateConfigFile(compilation, compiler, `${name}/${baseCompName}`, {
1139
+ const compConfig = {
985
1140
  component: true,
986
- styleIsolation: 'apply-shared',
1141
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
987
1142
  usingComponents: {
988
- [baseCompName]: `./${baseCompName}`,
989
- [customWrapperName]: `./${customWrapperName}`
1143
+ [exports.baseCompName]: `./${exports.baseCompName}`
990
1144
  }
991
- });
992
- this.generateTemplateFile(compilation, compiler, `${name}/${baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
1145
+ };
1146
+ if (isUsingCustomWrapper) {
1147
+ compConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1148
+ }
1149
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.baseCompName}`, compConfig);
1150
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
993
1151
  }
994
- this.generateConfigFile(compilation, compiler, `${name}/${customWrapperName}`, {
1152
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.customWrapperName}`, {
995
1153
  component: true,
996
- styleIsolation: 'apply-shared',
1154
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
997
1155
  usingComponents: {
998
- [customWrapperName]: `./${customWrapperName}`
1156
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
999
1157
  }
1000
1158
  });
1001
- this.generateTemplateFile(compilation, compiler, `${name}/${customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
1159
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
1002
1160
  this.generateXSFile(compilation, compiler, `${name}/utils`);
1003
1161
  });
1004
1162
  this.pages.forEach(page => {
@@ -1021,14 +1179,14 @@ class TaroMiniPlugin {
1021
1179
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1022
1180
  }
1023
1181
  if (config) {
1024
- const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(baseCompName, ''))));
1025
- const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(customWrapperName, ''))));
1182
+ const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(exports.baseCompName, ''))));
1183
+ const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(exports.customWrapperName, ''))));
1026
1184
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1027
1185
  if (isUsingCustomWrapper) {
1028
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1186
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1029
1187
  }
1030
1188
  if (!template.isSupportRecursive && !page.isNative) {
1031
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1189
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1032
1190
  }
1033
1191
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1034
1192
  }
@@ -1043,6 +1201,8 @@ class TaroMiniPlugin {
1043
1201
  const { modifyMiniConfigs } = combination.config;
1044
1202
  const baseTemplateName = 'base';
1045
1203
  const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
1204
+ let subPackageIndieCustomWrapperRoots = new Set();
1205
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1046
1206
  /**
1047
1207
  * 与原生小程序混写时解析模板与样式
1048
1208
  */
@@ -1062,47 +1222,55 @@ class TaroMiniPlugin {
1062
1222
  const appConfigName = node_path_1.default.basename(appConfigPath).replace(node_path_1.default.extname(appConfigPath), '');
1063
1223
  this.generateConfigFile(compilation, compiler, this.appEntry, this.filesConfig[appConfigName].content);
1064
1224
  }
1065
- if (!template.isSupportRecursive) {
1225
+ let skipRootTemplates = false;
1226
+ skipRootTemplates = this.hooks.modifySkipRootTemplates.call(skipRootTemplates);
1227
+ if (!template.isSupportRecursive && !skipRootTemplates) {
1066
1228
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
1067
- this.generateTemplateFile(compilation, compiler, baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1229
+ this.generateTemplateFile(compilation, compiler, exports.baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1068
1230
  const baseCompConfig = {
1069
1231
  component: true,
1070
- styleIsolation: 'apply-shared',
1232
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1071
1233
  usingComponents: {
1072
- [baseCompName]: `./${baseCompName}`
1234
+ [exports.baseCompName]: `./${exports.baseCompName}`
1073
1235
  }
1074
1236
  };
1075
1237
  if (isUsingCustomWrapper) {
1076
- baseCompConfig.usingComponents[customWrapperName] = `./${customWrapperName}`;
1077
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1238
+ baseCompConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1239
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1078
1240
  component: true,
1079
- styleIsolation: 'apply-shared',
1241
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1080
1242
  usingComponents: {
1081
- [baseCompName]: `./${baseCompName}`,
1082
- [customWrapperName]: `./${customWrapperName}`
1243
+ [exports.baseCompName]: `./${exports.baseCompName}`,
1244
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1083
1245
  }
1084
1246
  });
1085
1247
  }
1086
- this.generateConfigFile(compilation, compiler, baseCompName, baseCompConfig);
1248
+ this.generateConfigFile(compilation, compiler, exports.baseCompName, baseCompConfig);
1087
1249
  }
1088
- else {
1250
+ else if (!skipRootTemplates) {
1089
1251
  if (isUsingCustomWrapper) {
1090
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1252
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1091
1253
  component: true,
1092
- styleIsolation: 'apply-shared',
1254
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1093
1255
  usingComponents: {
1094
- [customWrapperName]: `./${customWrapperName}`
1256
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1095
1257
  }
1096
1258
  });
1097
1259
  }
1098
1260
  }
1099
- this.generateTemplateFile(compilation, compiler, baseTemplateName, template.buildTemplate, component_1.componentConfig);
1100
- isUsingCustomWrapper && this.generateTemplateFile(compilation, compiler, customWrapperName, template.buildCustomComponentTemplate, this.options.fileType.templ);
1101
- this.generateXSFile(compilation, compiler, 'utils');
1261
+ // 当配置了 mainPackageRoot 时,跳过根目录 base.wxml 和 utils.wxs 的生成
1262
+ if (!skipRootTemplates) {
1263
+ this.generateTemplateFile(compilation, compiler, baseTemplateName, template.buildTemplate, component_1.componentConfig);
1264
+ isUsingCustomWrapper && this.generateTemplateFile(compilation, compiler, exports.customWrapperName, template.buildCustomComponentTemplate, this.options.fileType.templ);
1265
+ this.generateXSFile(compilation, compiler, 'utils');
1266
+ }
1267
+ subPackageIndieCustomWrapperRoots = this.hooks.generateExtraFiles.call(subPackageIndieCustomWrapperRoots, compilation, compiler);
1268
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1102
1269
  this.components.forEach(component => {
1103
1270
  const importBaseTemplatePath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(component.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTemplatePath(baseTemplateName))));
1104
1271
  const config = this.filesConfig[this.getConfigFilePath(component.name)];
1105
1272
  if (config) {
1273
+ this.hooks.modifyComponentConfig.call({ config, component }, subPackageIndieCustomWrapperRoots);
1106
1274
  this.generateConfigFile(compilation, compiler, component.path, config.content);
1107
1275
  }
1108
1276
  if (!component.isNative) {
@@ -1110,31 +1278,46 @@ class TaroMiniPlugin {
1110
1278
  }
1111
1279
  });
1112
1280
  this.pages.forEach(page => {
1113
- const importBaseTemplatePath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTemplatePath(baseTemplateName))));
1281
+ let importBaseTemplatePath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTemplatePath(baseTemplateName))));
1114
1282
  const config = this.filesConfig[this.getConfigFilePath(page.name)];
1115
1283
  // pages 里面会混合独立分包的,在这里需要过滤一下,避免重复生成 assets
1116
1284
  const isIndependent = !!this.getIndependentPackage(page.path);
1117
1285
  if (isIndependent)
1118
1286
  return;
1119
1287
  // 生成页面模板需要在生成页面配置之前,因为会依赖到页面配置的部分内容
1288
+ let importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTargetFilePath(exports.baseCompName, ''))));
1289
+ let importCustomWrapperPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTargetFilePath(exports.customWrapperName, ''))));
1290
+ let isPageRecursiveDisabled = false;
1291
+ let shouldUseCustomWrapper = isUsingCustomWrapper;
1292
+ const pageConfigContext = this.hooks.modifyPageConfig.call({
1293
+ importBaseTemplatePath,
1294
+ importBaseCompPath,
1295
+ importCustomWrapperPath,
1296
+ shouldUseCustomWrapper,
1297
+ isPageRecursiveDisabled,
1298
+ }, page, subPackageIndieCustomWrapperRoots);
1299
+ importBaseTemplatePath = pageConfigContext.importBaseTemplatePath;
1300
+ importBaseCompPath = pageConfigContext.importBaseCompPath;
1301
+ importCustomWrapperPath = pageConfigContext.importCustomWrapperPath;
1302
+ shouldUseCustomWrapper = pageConfigContext.shouldUseCustomWrapper;
1303
+ isPageRecursiveDisabled = pageConfigContext.isPageRecursiveDisabled;
1120
1304
  if (!page.isNative) {
1121
1305
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1122
1306
  }
1123
1307
  if (config) {
1124
- const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTargetFilePath(baseCompName, ''))));
1125
- const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTargetFilePath(customWrapperName, ''))));
1126
1308
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1127
- if (isUsingCustomWrapper) {
1128
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1309
+ if (shouldUseCustomWrapper) {
1310
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1129
1311
  }
1130
- if (!template.isSupportRecursive && !page.isNative) {
1131
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1312
+ if (!template.isSupportRecursive && !page.isNative && !isPageRecursiveDisabled) {
1313
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1132
1314
  }
1133
1315
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1134
1316
  }
1135
1317
  });
1136
1318
  this.generateTabBarFiles(compilation, compiler);
1137
1319
  this.injectCommonStyles(compilation, compiler);
1320
+ this.hooks.afterGenerateFiles.call(compilation, compiler);
1138
1321
  if (this.themeLocation) {
1139
1322
  this.generateDarkModeFile(compilation, compiler);
1140
1323
  }
@@ -1167,12 +1350,15 @@ class TaroMiniPlugin {
1167
1350
  delete compilation.assets[assetPath];
1168
1351
  }
1169
1352
  });
1353
+ this.hooks.optimizeAssets.call(compilation);
1170
1354
  });
1171
1355
  }
1172
1356
  generateConfigFile(compilation, compiler, filePath, config) {
1173
1357
  const { RawSource } = compiler.webpack.sources;
1174
1358
  const fileConfigName = this.getConfigPath(this.getComponentName(filePath));
1175
- const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components'];
1359
+ const componentName = this.getComponentName(filePath);
1360
+ config = this.hooks.modifyConfig.call(config, componentName);
1361
+ const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components', 'forceCustomWrapper'];
1176
1362
  unofficialConfigs.forEach(item => {
1177
1363
  delete config[item];
1178
1364
  });
@@ -1318,12 +1504,21 @@ class TaroMiniPlugin {
1318
1504
  });
1319
1505
  });
1320
1506
  }
1321
- if (commons.size() > 0) {
1507
+ // 判断是否需要处理样式:有 common chunks 或者有 app.wxss(可被扩展插件修改)
1508
+ const hasAppStyle = !!assets[appStyle];
1509
+ let shouldProcessStyles = commons.size() > 0;
1510
+ if (!hasAppStyle) {
1511
+ shouldProcessStyles = false;
1512
+ }
1513
+ shouldProcessStyles = this.hooks.modifyShouldProcessStyles.call(shouldProcessStyles);
1514
+ if (shouldProcessStyles) {
1322
1515
  const APP_STYLE_NAME = 'app-origin' + styleExt;
1323
1516
  assets[APP_STYLE_NAME] = new ConcatSource(originSource);
1324
1517
  const source = new ConcatSource('');
1325
1518
  source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(APP_STYLE_NAME))};`);
1326
- source.add(commons);
1519
+ if (commons.size() > 0) {
1520
+ source.add(commons);
1521
+ }
1327
1522
  source.add('\n');
1328
1523
  assets[appStyle] = source;
1329
1524
  if (newBlended) {
@@ -1339,14 +1534,43 @@ class TaroMiniPlugin {
1339
1534
  }
1340
1535
  const source = new ConcatSource('');
1341
1536
  const originSource = assets[pageStyle];
1342
- componentCommons.forEach(item => {
1343
- source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(node_path_1.default.posix.relative(node_path_1.default.dirname(pageStyle), item)))};\n`);
1344
- });
1537
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1538
+ importStatement: '',
1539
+ shouldSkip: false,
1540
+ isMainPackageRoot: false,
1541
+ }, page);
1542
+ if (styleImportContext.shouldSkip) {
1543
+ // no-op
1544
+ }
1545
+ else if (styleImportContext.importStatement) {
1546
+ source.add(styleImportContext.importStatement);
1547
+ }
1548
+ else {
1549
+ componentCommons.forEach(item => {
1550
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(node_path_1.default.posix.relative(node_path_1.default.dirname(pageStyle), item)))};\n`);
1551
+ });
1552
+ }
1345
1553
  source.add(originSource);
1346
1554
  assets[pageStyle] = source;
1347
1555
  }
1348
1556
  else {
1349
- if (pageStyle in assets) {
1557
+ // 普通页面(非本地化组件)
1558
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1559
+ importStatement: '',
1560
+ shouldSkip: false,
1561
+ isMainPackageRoot: false,
1562
+ }, page);
1563
+ if (styleImportContext.importStatement) {
1564
+ const source = new ConcatSource('');
1565
+ if (pageStyle in assets) {
1566
+ source.add(assets[pageStyle]);
1567
+ }
1568
+ const importSource = new ConcatSource('');
1569
+ importSource.add(styleImportContext.importStatement);
1570
+ importSource.add(source);
1571
+ assets[pageStyle] = importSource;
1572
+ }
1573
+ else if (pageStyle in assets) {
1350
1574
  const source = new ConcatSource('');
1351
1575
  const originSource = assets[pageStyle];
1352
1576
  source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(node_path_1.default.posix.relative(node_path_1.default.dirname(pageStyle), 'app' + styleExt)))};\n`);