@tarojs/webpack5-runner 4.2.1-beta.0 → 4.2.1-beta.2

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 +261 -56
  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
  }
@@ -613,8 +700,11 @@ class TaroMiniPlugin {
613
700
  */
614
701
  addEntry(entryPath, entryName, entryType, options = {}) {
615
702
  let dep;
616
- if (this.dependencies.has(entryPath)) {
617
- dep = this.dependencies.get(entryPath);
703
+ // 对于 STATIC 类型(如 comp/custom-wrapper),使用 entryName 作为 key 的一部分
704
+ // 这允许同一个模板文件被多次添加为不同名称的入口
705
+ const depKey = entryType === helper_1.META_TYPE.STATIC ? `${entryPath}#${entryName}` : entryPath;
706
+ if (this.dependencies.has(depKey)) {
707
+ dep = this.dependencies.get(depKey);
618
708
  dep.name = entryName;
619
709
  dep.loc = { name: entryName };
620
710
  dep.request = entryPath;
@@ -625,7 +715,7 @@ class TaroMiniPlugin {
625
715
  else {
626
716
  dep = new TaroSingleEntryDependency_1.default(entryPath, entryName, { name: entryName }, entryType, options);
627
717
  }
628
- this.dependencies.set(entryPath, dep);
718
+ this.dependencies.set(depKey, dep);
629
719
  }
630
720
  /**
631
721
  * 在 this.dependencies 中新增或修改 app、模板组件、页面、组件等资源模块
@@ -633,10 +723,17 @@ class TaroMiniPlugin {
633
723
  addEntries() {
634
724
  const { template } = this.options;
635
725
  this.addEntry(this.appEntry, 'app', helper_1.META_TYPE.ENTRY);
636
- if (!template.isSupportRecursive) {
726
+ const entryFlags = this.hooks.modifyEntries.call({
727
+ skipRootComp: false,
728
+ skipRootWrapper: false,
729
+ });
730
+ if (!template.isSupportRecursive && !entryFlags.skipRootComp) {
637
731
  this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/comp'), 'comp', helper_1.META_TYPE.STATIC);
638
732
  }
639
- this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
733
+ if (!entryFlags.skipRootWrapper) {
734
+ this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
735
+ }
736
+ // subPackageIndie 下的 comp/custom-wrapper 统一走独立子编译器,避免被主编译的公共 chunk 共享
640
737
  this.pages.forEach(item => {
641
738
  if (item.isNative) {
642
739
  this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
@@ -666,6 +763,39 @@ class TaroMiniPlugin {
666
763
  }
667
764
  });
668
765
  }
766
+ computeForceCustomWrapperForWebpackMainComp() {
767
+ var _a;
768
+ if (this.options.template.isSupportRecursive)
769
+ return false;
770
+ const independentPaths = new Set();
771
+ this.independentPackages.forEach(({ pages }) => {
772
+ pages.forEach(p => independentPaths.add(p));
773
+ });
774
+ for (const page of this.pages) {
775
+ if (page.isNative || independentPaths.has(page.path))
776
+ continue;
777
+ const content = (_a = this.filesConfig[this.getConfigFilePath(page.name)]) === null || _a === void 0 ? void 0 : _a.content;
778
+ if (content === null || content === void 0 ? void 0 : content.forceCustomWrapper)
779
+ return true;
780
+ }
781
+ return false;
782
+ }
783
+ computeForceCustomWrapperForIndieRoot(pages) {
784
+ return (0, forceCustomWrapper_1.computeForceCustomWrapperForIndependentPackage)(pages, this.pages, this.filesConfig, (p) => this.getConfigFilePath(p));
785
+ }
786
+ applyForceCustomWrapperDefine(compiler) {
787
+ if (this.options.template.isSupportRecursive)
788
+ return;
789
+ const value = JSON.stringify(this.computeForceCustomWrapperForWebpackMainComp());
790
+ if (!this.forceCustomWrapperDefineDefinitions) {
791
+ this.forceCustomWrapperDefineDefinitions = {
792
+ TARO_FORCE_CUSTOM_WRAPPER: value
793
+ };
794
+ new compiler.webpack.DefinePlugin(this.forceCustomWrapperDefineDefinitions).apply(compiler);
795
+ return;
796
+ }
797
+ this.forceCustomWrapperDefineDefinitions.TARO_FORCE_CUSTOM_WRAPPER = value;
798
+ }
669
799
  replaceExt(file, ext) {
670
800
  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
801
  }
@@ -825,7 +955,7 @@ class TaroMiniPlugin {
825
955
  filename: `[name]${this.options.fileType.style}`,
826
956
  chunkFilename: `[name]${this.options.fileType.style}`
827
957
  }).apply(childCompiler);
828
- new compiler.webpack.DefinePlugin(this.options.constantsReplaceList).apply(childCompiler);
958
+ new compiler.webpack.DefinePlugin(Object.assign(Object.assign({}, this.options.constantsReplaceList), { TARO_FORCE_CUSTOM_WRAPPER: JSON.stringify(this.computeForceCustomWrapperForIndieRoot(pages)) })).apply(childCompiler);
829
959
  if (compiler.options.optimization) {
830
960
  new SplitChunksPlugin({
831
961
  chunks: 'all',
@@ -965,6 +1095,12 @@ class TaroMiniPlugin {
965
1095
  usingComponents[key] = match ? `${node_path_1.default.sep}${match[0]}` : compPath;
966
1096
  }
967
1097
  }
1098
+ cloneThirdPartyComponent(thirdPartyComponents, componentName) {
1099
+ const attrs = component_1.componentConfig.thirdPartyComponents.get(componentName);
1100
+ if (!attrs || thirdPartyComponents.has(componentName))
1101
+ return;
1102
+ thirdPartyComponents.set(componentName, new Set(attrs));
1103
+ }
968
1104
  /** 生成小程序独立分包的相关文件 */
969
1105
  generateIndependentMiniFiles(compilation, compiler) {
970
1106
  return __awaiter(this, void 0, void 0, function* () {
@@ -981,24 +1117,27 @@ class TaroMiniPlugin {
981
1117
  this.generateTemplateFile(compilation, compiler, `${name}/${baseTemplateName}`, template.buildTemplate, component_1.componentConfig);
982
1118
  if (!template.isSupportRecursive) {
983
1119
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
984
- this.generateConfigFile(compilation, compiler, `${name}/${baseCompName}`, {
1120
+ const compConfig = {
985
1121
  component: true,
986
- styleIsolation: 'apply-shared',
1122
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
987
1123
  usingComponents: {
988
- [baseCompName]: `./${baseCompName}`,
989
- [customWrapperName]: `./${customWrapperName}`
1124
+ [exports.baseCompName]: `./${exports.baseCompName}`
990
1125
  }
991
- });
992
- this.generateTemplateFile(compilation, compiler, `${name}/${baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
1126
+ };
1127
+ if (isUsingCustomWrapper) {
1128
+ compConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1129
+ }
1130
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.baseCompName}`, compConfig);
1131
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
993
1132
  }
994
- this.generateConfigFile(compilation, compiler, `${name}/${customWrapperName}`, {
1133
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.customWrapperName}`, {
995
1134
  component: true,
996
- styleIsolation: 'apply-shared',
1135
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
997
1136
  usingComponents: {
998
- [customWrapperName]: `./${customWrapperName}`
1137
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
999
1138
  }
1000
1139
  });
1001
- this.generateTemplateFile(compilation, compiler, `${name}/${customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
1140
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
1002
1141
  this.generateXSFile(compilation, compiler, `${name}/utils`);
1003
1142
  });
1004
1143
  this.pages.forEach(page => {
@@ -1021,14 +1160,14 @@ class TaroMiniPlugin {
1021
1160
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1022
1161
  }
1023
1162
  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, ''))));
1163
+ const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(exports.baseCompName, ''))));
1164
+ 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
1165
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1027
1166
  if (isUsingCustomWrapper) {
1028
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1167
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1029
1168
  }
1030
1169
  if (!template.isSupportRecursive && !page.isNative) {
1031
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1170
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1032
1171
  }
1033
1172
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1034
1173
  }
@@ -1043,6 +1182,8 @@ class TaroMiniPlugin {
1043
1182
  const { modifyMiniConfigs } = combination.config;
1044
1183
  const baseTemplateName = 'base';
1045
1184
  const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
1185
+ let subPackageIndieCustomWrapperRoots = new Set();
1186
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1046
1187
  /**
1047
1188
  * 与原生小程序混写时解析模板与样式
1048
1189
  */
@@ -1062,47 +1203,55 @@ class TaroMiniPlugin {
1062
1203
  const appConfigName = node_path_1.default.basename(appConfigPath).replace(node_path_1.default.extname(appConfigPath), '');
1063
1204
  this.generateConfigFile(compilation, compiler, this.appEntry, this.filesConfig[appConfigName].content);
1064
1205
  }
1065
- if (!template.isSupportRecursive) {
1206
+ let skipRootTemplates = false;
1207
+ skipRootTemplates = this.hooks.modifySkipRootTemplates.call(skipRootTemplates);
1208
+ if (!template.isSupportRecursive && !skipRootTemplates) {
1066
1209
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
1067
- this.generateTemplateFile(compilation, compiler, baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1210
+ this.generateTemplateFile(compilation, compiler, exports.baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1068
1211
  const baseCompConfig = {
1069
1212
  component: true,
1070
- styleIsolation: 'apply-shared',
1213
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1071
1214
  usingComponents: {
1072
- [baseCompName]: `./${baseCompName}`
1215
+ [exports.baseCompName]: `./${exports.baseCompName}`
1073
1216
  }
1074
1217
  };
1075
1218
  if (isUsingCustomWrapper) {
1076
- baseCompConfig.usingComponents[customWrapperName] = `./${customWrapperName}`;
1077
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1219
+ baseCompConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1220
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1078
1221
  component: true,
1079
- styleIsolation: 'apply-shared',
1222
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1080
1223
  usingComponents: {
1081
- [baseCompName]: `./${baseCompName}`,
1082
- [customWrapperName]: `./${customWrapperName}`
1224
+ [exports.baseCompName]: `./${exports.baseCompName}`,
1225
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1083
1226
  }
1084
1227
  });
1085
1228
  }
1086
- this.generateConfigFile(compilation, compiler, baseCompName, baseCompConfig);
1229
+ this.generateConfigFile(compilation, compiler, exports.baseCompName, baseCompConfig);
1087
1230
  }
1088
- else {
1231
+ else if (!skipRootTemplates) {
1089
1232
  if (isUsingCustomWrapper) {
1090
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1233
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1091
1234
  component: true,
1092
- styleIsolation: 'apply-shared',
1235
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1093
1236
  usingComponents: {
1094
- [customWrapperName]: `./${customWrapperName}`
1237
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1095
1238
  }
1096
1239
  });
1097
1240
  }
1098
1241
  }
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');
1242
+ // 当配置了 mainPackageRoot 时,跳过根目录 base.wxml 和 utils.wxs 的生成
1243
+ if (!skipRootTemplates) {
1244
+ this.generateTemplateFile(compilation, compiler, baseTemplateName, template.buildTemplate, component_1.componentConfig);
1245
+ isUsingCustomWrapper && this.generateTemplateFile(compilation, compiler, exports.customWrapperName, template.buildCustomComponentTemplate, this.options.fileType.templ);
1246
+ this.generateXSFile(compilation, compiler, 'utils');
1247
+ }
1248
+ subPackageIndieCustomWrapperRoots = this.hooks.generateExtraFiles.call(subPackageIndieCustomWrapperRoots, compilation, compiler);
1249
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1102
1250
  this.components.forEach(component => {
1103
1251
  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
1252
  const config = this.filesConfig[this.getConfigFilePath(component.name)];
1105
1253
  if (config) {
1254
+ this.hooks.modifyComponentConfig.call({ config, component }, subPackageIndieCustomWrapperRoots);
1106
1255
  this.generateConfigFile(compilation, compiler, component.path, config.content);
1107
1256
  }
1108
1257
  if (!component.isNative) {
@@ -1110,31 +1259,46 @@ class TaroMiniPlugin {
1110
1259
  }
1111
1260
  });
1112
1261
  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))));
1262
+ 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
1263
  const config = this.filesConfig[this.getConfigFilePath(page.name)];
1115
1264
  // pages 里面会混合独立分包的,在这里需要过滤一下,避免重复生成 assets
1116
1265
  const isIndependent = !!this.getIndependentPackage(page.path);
1117
1266
  if (isIndependent)
1118
1267
  return;
1119
1268
  // 生成页面模板需要在生成页面配置之前,因为会依赖到页面配置的部分内容
1269
+ 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, ''))));
1270
+ 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, ''))));
1271
+ let isPageRecursiveDisabled = false;
1272
+ let shouldUseCustomWrapper = isUsingCustomWrapper;
1273
+ const pageConfigContext = this.hooks.modifyPageConfig.call({
1274
+ importBaseTemplatePath,
1275
+ importBaseCompPath,
1276
+ importCustomWrapperPath,
1277
+ shouldUseCustomWrapper,
1278
+ isPageRecursiveDisabled,
1279
+ }, page, subPackageIndieCustomWrapperRoots);
1280
+ importBaseTemplatePath = pageConfigContext.importBaseTemplatePath;
1281
+ importBaseCompPath = pageConfigContext.importBaseCompPath;
1282
+ importCustomWrapperPath = pageConfigContext.importCustomWrapperPath;
1283
+ shouldUseCustomWrapper = pageConfigContext.shouldUseCustomWrapper;
1284
+ isPageRecursiveDisabled = pageConfigContext.isPageRecursiveDisabled;
1120
1285
  if (!page.isNative) {
1121
1286
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1122
1287
  }
1123
1288
  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
1289
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1127
- if (isUsingCustomWrapper) {
1128
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1290
+ if (shouldUseCustomWrapper) {
1291
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1129
1292
  }
1130
- if (!template.isSupportRecursive && !page.isNative) {
1131
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1293
+ if (!template.isSupportRecursive && !page.isNative && !isPageRecursiveDisabled) {
1294
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1132
1295
  }
1133
1296
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1134
1297
  }
1135
1298
  });
1136
1299
  this.generateTabBarFiles(compilation, compiler);
1137
1300
  this.injectCommonStyles(compilation, compiler);
1301
+ this.hooks.afterGenerateFiles.call(compilation, compiler);
1138
1302
  if (this.themeLocation) {
1139
1303
  this.generateDarkModeFile(compilation, compiler);
1140
1304
  }
@@ -1167,12 +1331,15 @@ class TaroMiniPlugin {
1167
1331
  delete compilation.assets[assetPath];
1168
1332
  }
1169
1333
  });
1334
+ this.hooks.optimizeAssets.call(compilation);
1170
1335
  });
1171
1336
  }
1172
1337
  generateConfigFile(compilation, compiler, filePath, config) {
1173
1338
  const { RawSource } = compiler.webpack.sources;
1174
1339
  const fileConfigName = this.getConfigPath(this.getComponentName(filePath));
1175
- const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components'];
1340
+ const componentName = this.getComponentName(filePath);
1341
+ config = this.hooks.modifyConfig.call(config, componentName);
1342
+ const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components', 'forceCustomWrapper'];
1176
1343
  unofficialConfigs.forEach(item => {
1177
1344
  delete config[item];
1178
1345
  });
@@ -1318,12 +1485,21 @@ class TaroMiniPlugin {
1318
1485
  });
1319
1486
  });
1320
1487
  }
1321
- if (commons.size() > 0) {
1488
+ // 判断是否需要处理样式:有 common chunks 或者有 app.wxss(可被扩展插件修改)
1489
+ const hasAppStyle = !!assets[appStyle];
1490
+ let shouldProcessStyles = commons.size() > 0;
1491
+ if (!hasAppStyle) {
1492
+ shouldProcessStyles = false;
1493
+ }
1494
+ shouldProcessStyles = this.hooks.modifyShouldProcessStyles.call(shouldProcessStyles);
1495
+ if (shouldProcessStyles) {
1322
1496
  const APP_STYLE_NAME = 'app-origin' + styleExt;
1323
1497
  assets[APP_STYLE_NAME] = new ConcatSource(originSource);
1324
1498
  const source = new ConcatSource('');
1325
1499
  source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(APP_STYLE_NAME))};`);
1326
- source.add(commons);
1500
+ if (commons.size() > 0) {
1501
+ source.add(commons);
1502
+ }
1327
1503
  source.add('\n');
1328
1504
  assets[appStyle] = source;
1329
1505
  if (newBlended) {
@@ -1339,14 +1515,43 @@ class TaroMiniPlugin {
1339
1515
  }
1340
1516
  const source = new ConcatSource('');
1341
1517
  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
- });
1518
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1519
+ importStatement: '',
1520
+ shouldSkip: false,
1521
+ isMainPackageRoot: false,
1522
+ }, page);
1523
+ if (styleImportContext.shouldSkip) {
1524
+ // no-op
1525
+ }
1526
+ else if (styleImportContext.importStatement) {
1527
+ source.add(styleImportContext.importStatement);
1528
+ }
1529
+ else {
1530
+ componentCommons.forEach(item => {
1531
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(node_path_1.default.posix.relative(node_path_1.default.dirname(pageStyle), item)))};\n`);
1532
+ });
1533
+ }
1345
1534
  source.add(originSource);
1346
1535
  assets[pageStyle] = source;
1347
1536
  }
1348
1537
  else {
1349
- if (pageStyle in assets) {
1538
+ // 普通页面(非本地化组件)
1539
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1540
+ importStatement: '',
1541
+ shouldSkip: false,
1542
+ isMainPackageRoot: false,
1543
+ }, page);
1544
+ if (styleImportContext.importStatement) {
1545
+ const source = new ConcatSource('');
1546
+ if (pageStyle in assets) {
1547
+ source.add(assets[pageStyle]);
1548
+ }
1549
+ const importSource = new ConcatSource('');
1550
+ importSource.add(styleImportContext.importStatement);
1551
+ importSource.add(source);
1552
+ assets[pageStyle] = importSource;
1553
+ }
1554
+ else if (pageStyle in assets) {
1350
1555
  const source = new ConcatSource('');
1351
1556
  const originSource = assets[pageStyle];
1352
1557
  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`);