@tarojs/webpack5-runner 4.2.2-alpha.2 → 4.2.2-alpha.3

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 (30) hide show
  1. package/dist/plugins/AsyncSubPackagePlugin.js +489 -0
  2. package/dist/plugins/AsyncSubPackagePlugin.js.map +1 -0
  3. package/dist/plugins/BuildNativePlugin.js +15 -11
  4. package/dist/plugins/BuildNativePlugin.js.map +1 -1
  5. package/dist/plugins/HarmonyPlugin.js +1 -1
  6. package/dist/plugins/HarmonyPlugin.js.map +1 -1
  7. package/dist/plugins/MiniCompileModePlugin.js +49 -4
  8. package/dist/plugins/MiniCompileModePlugin.js.map +1 -1
  9. package/dist/plugins/MiniPlugin.js +274 -57
  10. package/dist/plugins/MiniPlugin.js.map +1 -1
  11. package/dist/plugins/SubPackageIndiePlugin.js +1022 -0
  12. package/dist/plugins/SubPackageIndiePlugin.js.map +1 -0
  13. package/dist/plugins/TaroNormalModule.js +16 -0
  14. package/dist/plugins/TaroNormalModule.js.map +1 -1
  15. package/dist/plugins/TaroNormalModulesPlugin.js +127 -6
  16. package/dist/plugins/TaroNormalModulesPlugin.js.map +1 -1
  17. package/dist/plugins/TaroSingleEntryPlugin.js +1 -1
  18. package/dist/plugins/TaroSingleEntryPlugin.js.map +1 -1
  19. package/dist/template/comp.js +2 -1
  20. package/dist/utils/asyncSubPackage.js +106 -0
  21. package/dist/utils/asyncSubPackage.js.map +1 -0
  22. package/dist/utils/component.js +2 -1
  23. package/dist/utils/component.js.map +1 -1
  24. package/dist/utils/forceCustomWrapper.js +17 -0
  25. package/dist/utils/forceCustomWrapper.js.map +1 -0
  26. package/dist/webpack/HarmonyWebpackPlugin.js +3 -1
  27. package/dist/webpack/HarmonyWebpackPlugin.js.map +1 -1
  28. package/dist/webpack/MiniBaseConfig.js +2 -0
  29. package/dist/webpack/MiniBaseConfig.js.map +1 -1
  30. package/package.json +12 -12
@@ -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,28 @@ 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");
21
46
  const component_1 = require("../utils/component");
47
+ const forceCustomWrapper_1 = require("../utils/forceCustomWrapper");
22
48
  const webpack_1 = require("../utils/webpack");
49
+ const AsyncSubPackagePlugin_1 = __importDefault(require("./AsyncSubPackagePlugin"));
50
+ const SubPackageIndiePlugin_1 = __importStar(require("./SubPackageIndiePlugin"));
23
51
  const TaroLoadChunksPlugin_1 = __importDefault(require("./TaroLoadChunksPlugin"));
24
52
  const TaroNormalModulesPlugin_1 = __importDefault(require("./TaroNormalModulesPlugin"));
25
53
  const TaroSingleEntryPlugin_1 = __importDefault(require("./TaroSingleEntryPlugin"));
26
- const baseCompName = 'comp';
27
- const customWrapperName = 'custom-wrapper';
54
+ exports.baseCompName = 'comp';
55
+ exports.customWrapperName = 'custom-wrapper';
28
56
  const PLUGIN_NAME = 'TaroMiniPlugin';
29
57
  const CHILD_COMPILER_TAG = 'child';
58
+ exports.STYLE_ISOLATION_APPLY_SHARED = 'apply-shared';
59
+ exports.STYLE_ISOLATION_SHARED = 'shared';
30
60
  function isLoaderExist(loaders, loaderName) {
31
61
  return loaders.some(item => item.loader === loaderName);
32
62
  }
@@ -46,6 +76,9 @@ class TaroMiniPlugin {
46
76
  this.dependencies = new Map();
47
77
  this.pageLoaderName = '@tarojs/taro-loader/lib/page';
48
78
  this.independentPackages = new Map();
79
+ this.asyncSubPackagePlugin = null;
80
+ this.subPackageIndiePlugin = null;
81
+ this.forceCustomWrapperDefineDefinitions = null;
49
82
  const { combination } = options;
50
83
  const miniBuildConfig = combination.config;
51
84
  const { template, baseLevel = 16, experimental } = miniBuildConfig;
@@ -69,6 +102,22 @@ class TaroMiniPlugin {
69
102
  hot: options.hot,
70
103
  loaderMeta: options.loaderMeta || {},
71
104
  };
105
+ // 初始化扩展钩子
106
+ this.hooks = {
107
+ modifyEntries: new tapable_1.SyncWaterfallHook(['entries']),
108
+ modifyChunkRequire: new tapable_1.SyncWaterfallHook(['result', 'chunkId', 'miniType']),
109
+ afterResolveModule: new tapable_1.SyncHook(['resolveData']),
110
+ compileExtraEntries: new tapable_1.SyncHook(['compiler', 'compilation', 'promises']),
111
+ modifySkipRootTemplates: new tapable_1.SyncWaterfallHook(['skip']),
112
+ generateExtraFiles: new tapable_1.SyncWaterfallHook(['customWrapperRoots', 'compilation', 'compiler']),
113
+ modifyPageConfig: new tapable_1.SyncWaterfallHook(['context', 'page', 'customWrapperRoots']),
114
+ modifyComponentConfig: new tapable_1.SyncHook(['context', 'customWrapperRoots']),
115
+ afterGenerateFiles: new tapable_1.SyncHook(['compilation', 'compiler']),
116
+ optimizeAssets: new tapable_1.SyncHook(['compilation']),
117
+ modifyConfig: new tapable_1.SyncWaterfallHook(['config', 'componentName']),
118
+ modifyStyleImport: new tapable_1.SyncWaterfallHook(['context', 'page']),
119
+ modifyShouldProcessStyles: new tapable_1.SyncWaterfallHook(['shouldProcess']),
120
+ };
72
121
  if (template.isSupportRecursive === false && baseLevel > 0) {
73
122
  template.baseLevel = baseLevel;
74
123
  }
@@ -99,11 +148,17 @@ class TaroMiniPlugin {
99
148
  apply(compiler) {
100
149
  this.context = compiler.context;
101
150
  this.appEntry = this.getAppEntry(compiler);
151
+ if (this.options.newBlended) {
152
+ this.subPackageIndiePlugin = new SubPackageIndiePlugin_1.default(this);
153
+ this.subPackageIndiePlugin.apply();
154
+ }
102
155
  const { commonChunks, combination, framework, isBuildPlugin, newBlended, } = this.options;
103
156
  const { addChunkPages, onCompilerMake, modifyBuildAssets, onParseCreateElement, } = combination.config;
104
157
  /** build mode */
105
158
  compiler.hooks.run.tapAsync(PLUGIN_NAME, this.tryAsync((compiler) => __awaiter(this, void 0, void 0, function* () {
106
159
  yield this.run(compiler);
160
+ this.applyForceCustomWrapperDefine(compiler);
161
+ this.applyAsyncSubPackagePlugin(compiler);
107
162
  new TaroLoadChunksPlugin_1.default({
108
163
  commonChunks: commonChunks,
109
164
  isBuildPlugin,
@@ -120,6 +175,8 @@ class TaroMiniPlugin {
120
175
  this.isWatch = true;
121
176
  }
122
177
  yield this.run(compiler);
178
+ this.applyForceCustomWrapperDefine(compiler);
179
+ this.applyAsyncSubPackagePlugin(compiler);
123
180
  if (!this.loadChunksPlugin) {
124
181
  this.loadChunksPlugin = new TaroLoadChunksPlugin_1.default({
125
182
  commonChunks: commonChunks,
@@ -137,6 +194,7 @@ class TaroMiniPlugin {
137
194
  const dependencies = this.dependencies;
138
195
  const promises = [];
139
196
  this.compileIndependentPages(compiler, compilation, dependencies, promises);
197
+ this.hooks.compileExtraEntries.call(compiler, compilation, promises);
140
198
  dependencies.forEach(dep => {
141
199
  promises.push(new Promise((resolve, reject) => {
142
200
  compilation.addEntry(this.options.sourceDir, dep, Object.assign({ name: dep.name }, dep.options), err => err ? reject(err) : resolve(null));
@@ -149,6 +207,11 @@ class TaroMiniPlugin {
149
207
  /** For Webpack compilation get factory from compilation.dependencyFactories by denpendence's constructor */
150
208
  compilation.dependencyFactories.set(EntryDependency_1.default, normalModuleFactory);
151
209
  compilation.dependencyFactories.set(TaroSingleEntryDependency_1.default, normalModuleFactory);
210
+ if (this.options.newBlended) {
211
+ normalModuleFactory.hooks.afterResolve.tap(PLUGIN_NAME, (resolveData) => {
212
+ this.hooks.afterResolveModule.call(resolveData);
213
+ });
214
+ }
152
215
  /**
153
216
  * webpack NormalModule 在 runLoaders 真正解析资源的前一刻,
154
217
  * 往 NormalModule.loaders 中插入对应的 Taro Loader
@@ -292,6 +355,10 @@ class TaroMiniPlugin {
292
355
  let source;
293
356
  const id = (0, webpack_1.getChunkIdOrName)(chunk);
294
357
  const { miniType } = entryModule;
358
+ const modifyResult = this.hooks.modifyChunkRequire.call({ source: modules, handled: false }, id, miniType);
359
+ if (modifyResult === null || modifyResult === void 0 ? void 0 : modifyResult.handled) {
360
+ return modifyResult.source;
361
+ }
295
362
  const entryChunk = [{ name: 'app' }];
296
363
  // 所有模块都依赖app.js,确保@tarojs\plugin-platform-xxx\dist\runtime.js先于@tarojs/runtime执行,避免Taro API未被初始化
297
364
  if (this.nativeComponents.has(id) || miniType === helper_1.META_TYPE.STATIC) {
@@ -300,7 +367,8 @@ class TaroMiniPlugin {
300
367
  source = (0, webpack_1.addRequireToSource)(id, modules, v);
301
368
  }
302
369
  });
303
- return source;
370
+ // 如果没有依赖需要注入,返回原始模块
371
+ return source || modules;
304
372
  }
305
373
  else if (miniType === helper_1.META_TYPE.PAGE) {
306
374
  return (0, webpack_1.addRequireToSource)(id, modules, entryChunk);
@@ -309,6 +377,23 @@ class TaroMiniPlugin {
309
377
  });
310
378
  });
311
379
  }
380
+ /**
381
+ * 初始化异步分包插件。
382
+ * MiniPlugin 仅作为桥接,具体的 babel 注入、chunk 处理和 app.json 注册由 AsyncSubPackagePlugin 承担。
383
+ */
384
+ applyAsyncSubPackagePlugin(compiler) {
385
+ if (!this.subPackageIndiePlugin)
386
+ return;
387
+ const asyncRootMap = this.subPackageIndiePlugin.getAsyncSubPackageRootMap();
388
+ if (asyncRootMap.size === 0)
389
+ return;
390
+ if (!this.asyncSubPackagePlugin) {
391
+ this.asyncSubPackagePlugin = new AsyncSubPackagePlugin_1.default(this);
392
+ }
393
+ this.asyncSubPackagePlugin.updateAsyncRootMap(asyncRootMap);
394
+ this.asyncSubPackagePlugin.updateAsyncRuntimeRoots(this.subPackageIndiePlugin.getAsyncSubPackageRuntimeRoots());
395
+ this.asyncSubPackagePlugin.apply(compiler);
396
+ }
312
397
  /**
313
398
  * 根据 webpack entry 配置获取入口文件路径
314
399
  * @returns app 入口文件路径
@@ -354,6 +439,8 @@ class TaroMiniPlugin {
354
439
  */
355
440
  run(compiler) {
356
441
  return __awaiter(this, void 0, void 0, function* () {
442
+ var _a;
443
+ (_a = this.subPackageIndiePlugin) === null || _a === void 0 ? void 0 : _a.invalidateRunCache();
357
444
  if (this.options.isBuildPlugin) {
358
445
  this.getPluginFiles();
359
446
  this.getConfigFiles(compiler);
@@ -479,12 +566,12 @@ class TaroMiniPlugin {
479
566
  }
480
567
  if (!this.options.template.isSupportRecursive) {
481
568
  pluginJSON.publicComponents = Object.assign({}, publicComponents, {
482
- [baseCompName]: baseCompName
569
+ [exports.baseCompName]: exports.baseCompName
483
570
  });
484
571
  }
485
572
  if (isUsingCustomWrapper) {
486
573
  pluginJSON.publicComponents = Object.assign({}, publicComponents, {
487
- [customWrapperName]: customWrapperName
574
+ [exports.customWrapperName]: exports.customWrapperName
488
575
  });
489
576
  }
490
577
  }
@@ -530,7 +617,19 @@ class TaroMiniPlugin {
530
617
  }
531
618
  const { newBlended, frameworkExts, combination } = this.options;
532
619
  const { prerender } = combination.config;
533
- this.prerenderPages = new Set((0, prerender_1.validatePrerenderPages)(appPages, prerender).map(p => p.path));
620
+ // Collect sub-package pages so they are also eligible for prerender.
621
+ // `getPages` previously only fed main-package `appPages` into `prerenderPages`,
622
+ // so sub-package pages never received the `wx._prerender` injection and their
623
+ // prerender snapshots silently fell back to the previous page's instance.
624
+ const subPackages = this.appConfig.subPackages || this.appConfig.subpackages || [];
625
+ const subPages = [];
626
+ for (const sp of subPackages) {
627
+ const root = sp.root || '';
628
+ for (const pg of (sp.pages || [])) {
629
+ subPages.push(`${root}/${pg}`.replace(/\/{2,}/g, '/'));
630
+ }
631
+ }
632
+ this.prerenderPages = new Set((0, prerender_1.validatePrerenderPages)([...appPages, ...subPages], prerender).map(p => p.path));
534
633
  this.getTabBarFiles(this.appConfig);
535
634
  this.pages = new Set([
536
635
  ...appPages.map(item => {
@@ -613,8 +712,11 @@ class TaroMiniPlugin {
613
712
  */
614
713
  addEntry(entryPath, entryName, entryType, options = {}) {
615
714
  let dep;
616
- if (this.dependencies.has(entryPath)) {
617
- dep = this.dependencies.get(entryPath);
715
+ // ★ 对于 STATIC 类型(如 comp/custom-wrapper),使用 entryName 作为 key 的一部分
716
+ // 这允许同一个模板文件被多次添加为不同名称的入口
717
+ const depKey = entryType === helper_1.META_TYPE.STATIC ? `${entryPath}#${entryName}` : entryPath;
718
+ if (this.dependencies.has(depKey)) {
719
+ dep = this.dependencies.get(depKey);
618
720
  dep.name = entryName;
619
721
  dep.loc = { name: entryName };
620
722
  dep.request = entryPath;
@@ -625,7 +727,7 @@ class TaroMiniPlugin {
625
727
  else {
626
728
  dep = new TaroSingleEntryDependency_1.default(entryPath, entryName, { name: entryName }, entryType, options);
627
729
  }
628
- this.dependencies.set(entryPath, dep);
730
+ this.dependencies.set(depKey, dep);
629
731
  }
630
732
  /**
631
733
  * 在 this.dependencies 中新增或修改 app、模板组件、页面、组件等资源模块
@@ -633,10 +735,17 @@ class TaroMiniPlugin {
633
735
  addEntries() {
634
736
  const { template } = this.options;
635
737
  this.addEntry(this.appEntry, 'app', helper_1.META_TYPE.ENTRY);
636
- if (!template.isSupportRecursive) {
738
+ const entryFlags = this.hooks.modifyEntries.call({
739
+ skipRootComp: false,
740
+ skipRootWrapper: false,
741
+ });
742
+ if (!template.isSupportRecursive && !entryFlags.skipRootComp) {
637
743
  this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/comp'), 'comp', helper_1.META_TYPE.STATIC);
638
744
  }
639
- this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
745
+ if (!entryFlags.skipRootWrapper) {
746
+ this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
747
+ }
748
+ // subPackageIndie 下的 comp/custom-wrapper 统一走独立子编译器,避免被主编译的公共 chunk 共享
640
749
  this.pages.forEach(item => {
641
750
  if (item.isNative) {
642
751
  this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
@@ -666,6 +775,39 @@ class TaroMiniPlugin {
666
775
  }
667
776
  });
668
777
  }
778
+ computeForceCustomWrapperForWebpackMainComp() {
779
+ var _a;
780
+ if (this.options.template.isSupportRecursive)
781
+ return false;
782
+ const independentPaths = new Set();
783
+ this.independentPackages.forEach(({ pages }) => {
784
+ pages.forEach(p => independentPaths.add(p));
785
+ });
786
+ for (const page of this.pages) {
787
+ if (page.isNative || independentPaths.has(page.path))
788
+ continue;
789
+ const content = (_a = this.filesConfig[this.getConfigFilePath(page.name)]) === null || _a === void 0 ? void 0 : _a.content;
790
+ if (content === null || content === void 0 ? void 0 : content.forceCustomWrapper)
791
+ return true;
792
+ }
793
+ return false;
794
+ }
795
+ computeForceCustomWrapperForIndieRoot(pages) {
796
+ return (0, forceCustomWrapper_1.computeForceCustomWrapperForIndependentPackage)(pages, this.pages, this.filesConfig, (p) => this.getConfigFilePath(p));
797
+ }
798
+ applyForceCustomWrapperDefine(compiler) {
799
+ if (this.options.template.isSupportRecursive)
800
+ return;
801
+ const value = JSON.stringify(this.computeForceCustomWrapperForWebpackMainComp());
802
+ if (!this.forceCustomWrapperDefineDefinitions) {
803
+ this.forceCustomWrapperDefineDefinitions = {
804
+ TARO_FORCE_CUSTOM_WRAPPER: value
805
+ };
806
+ new compiler.webpack.DefinePlugin(this.forceCustomWrapperDefineDefinitions).apply(compiler);
807
+ return;
808
+ }
809
+ this.forceCustomWrapperDefineDefinitions.TARO_FORCE_CUSTOM_WRAPPER = value;
810
+ }
669
811
  replaceExt(file, ext) {
670
812
  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
813
  }
@@ -825,7 +967,7 @@ class TaroMiniPlugin {
825
967
  filename: `[name]${this.options.fileType.style}`,
826
968
  chunkFilename: `[name]${this.options.fileType.style}`
827
969
  }).apply(childCompiler);
828
- new compiler.webpack.DefinePlugin(this.options.constantsReplaceList).apply(childCompiler);
970
+ new compiler.webpack.DefinePlugin(Object.assign(Object.assign({}, this.options.constantsReplaceList), { TARO_FORCE_CUSTOM_WRAPPER: JSON.stringify(this.computeForceCustomWrapperForIndieRoot(pages)) })).apply(childCompiler);
829
971
  if (compiler.options.optimization) {
830
972
  new SplitChunksPlugin({
831
973
  chunks: 'all',
@@ -965,6 +1107,12 @@ class TaroMiniPlugin {
965
1107
  usingComponents[key] = match ? `${node_path_1.default.sep}${match[0]}` : compPath;
966
1108
  }
967
1109
  }
1110
+ cloneThirdPartyComponent(thirdPartyComponents, componentName) {
1111
+ const attrs = component_1.componentConfig.thirdPartyComponents.get(componentName);
1112
+ if (!attrs || thirdPartyComponents.has(componentName))
1113
+ return;
1114
+ thirdPartyComponents.set(componentName, new Set(attrs));
1115
+ }
968
1116
  /** 生成小程序独立分包的相关文件 */
969
1117
  generateIndependentMiniFiles(compilation, compiler) {
970
1118
  return __awaiter(this, void 0, void 0, function* () {
@@ -981,24 +1129,27 @@ class TaroMiniPlugin {
981
1129
  this.generateTemplateFile(compilation, compiler, `${name}/${baseTemplateName}`, template.buildTemplate, component_1.componentConfig);
982
1130
  if (!template.isSupportRecursive) {
983
1131
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
984
- this.generateConfigFile(compilation, compiler, `${name}/${baseCompName}`, {
1132
+ const compConfig = {
985
1133
  component: true,
986
- styleIsolation: 'apply-shared',
1134
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
987
1135
  usingComponents: {
988
- [baseCompName]: `./${baseCompName}`,
989
- [customWrapperName]: `./${customWrapperName}`
1136
+ [exports.baseCompName]: `./${exports.baseCompName}`
990
1137
  }
991
- });
992
- this.generateTemplateFile(compilation, compiler, `${name}/${baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
1138
+ };
1139
+ if (isUsingCustomWrapper) {
1140
+ compConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1141
+ }
1142
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.baseCompName}`, compConfig);
1143
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
993
1144
  }
994
- this.generateConfigFile(compilation, compiler, `${name}/${customWrapperName}`, {
1145
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.customWrapperName}`, {
995
1146
  component: true,
996
- styleIsolation: 'apply-shared',
1147
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
997
1148
  usingComponents: {
998
- [customWrapperName]: `./${customWrapperName}`
1149
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
999
1150
  }
1000
1151
  });
1001
- this.generateTemplateFile(compilation, compiler, `${name}/${customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
1152
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
1002
1153
  this.generateXSFile(compilation, compiler, `${name}/utils`);
1003
1154
  });
1004
1155
  this.pages.forEach(page => {
@@ -1021,14 +1172,14 @@ class TaroMiniPlugin {
1021
1172
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1022
1173
  }
1023
1174
  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, ''))));
1175
+ const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(exports.baseCompName, ''))));
1176
+ 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
1177
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1027
1178
  if (isUsingCustomWrapper) {
1028
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1179
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1029
1180
  }
1030
1181
  if (!template.isSupportRecursive && !page.isNative) {
1031
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1182
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1032
1183
  }
1033
1184
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1034
1185
  }
@@ -1043,6 +1194,8 @@ class TaroMiniPlugin {
1043
1194
  const { modifyMiniConfigs } = combination.config;
1044
1195
  const baseTemplateName = 'base';
1045
1196
  const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
1197
+ let subPackageIndieCustomWrapperRoots = new Set();
1198
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1046
1199
  /**
1047
1200
  * 与原生小程序混写时解析模板与样式
1048
1201
  */
@@ -1062,47 +1215,55 @@ class TaroMiniPlugin {
1062
1215
  const appConfigName = node_path_1.default.basename(appConfigPath).replace(node_path_1.default.extname(appConfigPath), '');
1063
1216
  this.generateConfigFile(compilation, compiler, this.appEntry, this.filesConfig[appConfigName].content);
1064
1217
  }
1065
- if (!template.isSupportRecursive) {
1218
+ let skipRootTemplates = false;
1219
+ skipRootTemplates = this.hooks.modifySkipRootTemplates.call(skipRootTemplates);
1220
+ if (!template.isSupportRecursive && !skipRootTemplates) {
1066
1221
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
1067
- this.generateTemplateFile(compilation, compiler, baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1222
+ this.generateTemplateFile(compilation, compiler, exports.baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1068
1223
  const baseCompConfig = {
1069
1224
  component: true,
1070
- styleIsolation: 'apply-shared',
1225
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1071
1226
  usingComponents: {
1072
- [baseCompName]: `./${baseCompName}`
1227
+ [exports.baseCompName]: `./${exports.baseCompName}`
1073
1228
  }
1074
1229
  };
1075
1230
  if (isUsingCustomWrapper) {
1076
- baseCompConfig.usingComponents[customWrapperName] = `./${customWrapperName}`;
1077
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1231
+ baseCompConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1232
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1078
1233
  component: true,
1079
- styleIsolation: 'apply-shared',
1234
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1080
1235
  usingComponents: {
1081
- [baseCompName]: `./${baseCompName}`,
1082
- [customWrapperName]: `./${customWrapperName}`
1236
+ [exports.baseCompName]: `./${exports.baseCompName}`,
1237
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1083
1238
  }
1084
1239
  });
1085
1240
  }
1086
- this.generateConfigFile(compilation, compiler, baseCompName, baseCompConfig);
1241
+ this.generateConfigFile(compilation, compiler, exports.baseCompName, baseCompConfig);
1087
1242
  }
1088
- else {
1243
+ else if (!skipRootTemplates) {
1089
1244
  if (isUsingCustomWrapper) {
1090
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1245
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1091
1246
  component: true,
1092
- styleIsolation: 'apply-shared',
1247
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1093
1248
  usingComponents: {
1094
- [customWrapperName]: `./${customWrapperName}`
1249
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1095
1250
  }
1096
1251
  });
1097
1252
  }
1098
1253
  }
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');
1254
+ // ★ 当配置了 mainPackageRoot 时,跳过根目录 base.wxml 和 utils.wxs 的生成
1255
+ if (!skipRootTemplates) {
1256
+ this.generateTemplateFile(compilation, compiler, baseTemplateName, template.buildTemplate, component_1.componentConfig);
1257
+ isUsingCustomWrapper && this.generateTemplateFile(compilation, compiler, exports.customWrapperName, template.buildCustomComponentTemplate, this.options.fileType.templ);
1258
+ this.generateXSFile(compilation, compiler, 'utils');
1259
+ }
1260
+ subPackageIndieCustomWrapperRoots = this.hooks.generateExtraFiles.call(subPackageIndieCustomWrapperRoots, compilation, compiler);
1261
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1102
1262
  this.components.forEach(component => {
1103
1263
  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
1264
  const config = this.filesConfig[this.getConfigFilePath(component.name)];
1105
1265
  if (config) {
1266
+ this.hooks.modifyComponentConfig.call({ config, component }, subPackageIndieCustomWrapperRoots);
1106
1267
  this.generateConfigFile(compilation, compiler, component.path, config.content);
1107
1268
  }
1108
1269
  if (!component.isNative) {
@@ -1110,31 +1271,46 @@ class TaroMiniPlugin {
1110
1271
  }
1111
1272
  });
1112
1273
  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))));
1274
+ 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
1275
  const config = this.filesConfig[this.getConfigFilePath(page.name)];
1115
1276
  // pages 里面会混合独立分包的,在这里需要过滤一下,避免重复生成 assets
1116
1277
  const isIndependent = !!this.getIndependentPackage(page.path);
1117
1278
  if (isIndependent)
1118
1279
  return;
1119
1280
  // 生成页面模板需要在生成页面配置之前,因为会依赖到页面配置的部分内容
1281
+ 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, ''))));
1282
+ 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, ''))));
1283
+ let isPageRecursiveDisabled = false;
1284
+ let shouldUseCustomWrapper = isUsingCustomWrapper;
1285
+ const pageConfigContext = this.hooks.modifyPageConfig.call({
1286
+ importBaseTemplatePath,
1287
+ importBaseCompPath,
1288
+ importCustomWrapperPath,
1289
+ shouldUseCustomWrapper,
1290
+ isPageRecursiveDisabled,
1291
+ }, page, subPackageIndieCustomWrapperRoots);
1292
+ importBaseTemplatePath = pageConfigContext.importBaseTemplatePath;
1293
+ importBaseCompPath = pageConfigContext.importBaseCompPath;
1294
+ importCustomWrapperPath = pageConfigContext.importCustomWrapperPath;
1295
+ shouldUseCustomWrapper = pageConfigContext.shouldUseCustomWrapper;
1296
+ isPageRecursiveDisabled = pageConfigContext.isPageRecursiveDisabled;
1120
1297
  if (!page.isNative) {
1121
1298
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1122
1299
  }
1123
1300
  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
1301
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1127
- if (isUsingCustomWrapper) {
1128
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1302
+ if (shouldUseCustomWrapper) {
1303
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1129
1304
  }
1130
- if (!template.isSupportRecursive && !page.isNative) {
1131
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1305
+ if (!template.isSupportRecursive && !page.isNative && !isPageRecursiveDisabled) {
1306
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1132
1307
  }
1133
1308
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1134
1309
  }
1135
1310
  });
1136
1311
  this.generateTabBarFiles(compilation, compiler);
1137
1312
  this.injectCommonStyles(compilation, compiler);
1313
+ this.hooks.afterGenerateFiles.call(compilation, compiler);
1138
1314
  if (this.themeLocation) {
1139
1315
  this.generateDarkModeFile(compilation, compiler);
1140
1316
  }
@@ -1167,12 +1343,15 @@ class TaroMiniPlugin {
1167
1343
  delete compilation.assets[assetPath];
1168
1344
  }
1169
1345
  });
1346
+ this.hooks.optimizeAssets.call(compilation);
1170
1347
  });
1171
1348
  }
1172
1349
  generateConfigFile(compilation, compiler, filePath, config) {
1173
1350
  const { RawSource } = compiler.webpack.sources;
1174
1351
  const fileConfigName = this.getConfigPath(this.getComponentName(filePath));
1175
- const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components'];
1352
+ const componentName = this.getComponentName(filePath);
1353
+ config = this.hooks.modifyConfig.call(config, componentName);
1354
+ const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components', 'forceCustomWrapper'];
1176
1355
  unofficialConfigs.forEach(item => {
1177
1356
  delete config[item];
1178
1357
  });
@@ -1318,12 +1497,21 @@ class TaroMiniPlugin {
1318
1497
  });
1319
1498
  });
1320
1499
  }
1321
- if (commons.size() > 0) {
1500
+ // 判断是否需要处理样式:有 common chunks 或者有 app.wxss(可被扩展插件修改)
1501
+ const hasAppStyle = !!assets[appStyle];
1502
+ let shouldProcessStyles = commons.size() > 0;
1503
+ if (!hasAppStyle) {
1504
+ shouldProcessStyles = false;
1505
+ }
1506
+ shouldProcessStyles = this.hooks.modifyShouldProcessStyles.call(shouldProcessStyles);
1507
+ if (shouldProcessStyles) {
1322
1508
  const APP_STYLE_NAME = 'app-origin' + styleExt;
1323
1509
  assets[APP_STYLE_NAME] = new ConcatSource(originSource);
1324
1510
  const source = new ConcatSource('');
1325
1511
  source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(APP_STYLE_NAME))};`);
1326
- source.add(commons);
1512
+ if (commons.size() > 0) {
1513
+ source.add(commons);
1514
+ }
1327
1515
  source.add('\n');
1328
1516
  assets[appStyle] = source;
1329
1517
  if (newBlended) {
@@ -1339,14 +1527,43 @@ class TaroMiniPlugin {
1339
1527
  }
1340
1528
  const source = new ConcatSource('');
1341
1529
  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
- });
1530
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1531
+ importStatement: '',
1532
+ shouldSkip: false,
1533
+ isMainPackageRoot: false,
1534
+ }, page);
1535
+ if (styleImportContext.shouldSkip) {
1536
+ // no-op
1537
+ }
1538
+ else if (styleImportContext.importStatement) {
1539
+ source.add(styleImportContext.importStatement);
1540
+ }
1541
+ else {
1542
+ componentCommons.forEach(item => {
1543
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(node_path_1.default.posix.relative(node_path_1.default.dirname(pageStyle), item)))};\n`);
1544
+ });
1545
+ }
1345
1546
  source.add(originSource);
1346
1547
  assets[pageStyle] = source;
1347
1548
  }
1348
1549
  else {
1349
- if (pageStyle in assets) {
1550
+ // 普通页面(非本地化组件)
1551
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1552
+ importStatement: '',
1553
+ shouldSkip: false,
1554
+ isMainPackageRoot: false,
1555
+ }, page);
1556
+ if (styleImportContext.importStatement) {
1557
+ const source = new ConcatSource('');
1558
+ if (pageStyle in assets) {
1559
+ source.add(assets[pageStyle]);
1560
+ }
1561
+ const importSource = new ConcatSource('');
1562
+ importSource.add(styleImportContext.importStatement);
1563
+ importSource.add(source);
1564
+ assets[pageStyle] = importSource;
1565
+ }
1566
+ else if (pageStyle in assets) {
1350
1567
  const source = new ConcatSource('');
1351
1568
  const originSource = assets[pageStyle];
1352
1569
  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`);