@tarojs/webpack5-runner 4.1.12-beta.6 → 4.1.12-beta.60

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.
@@ -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,
@@ -119,6 +174,8 @@ class TaroMiniPlugin {
119
174
  this.isWatch = true;
120
175
  }
121
176
  yield this.run(compiler);
177
+ this.applyForceCustomWrapperDefine(compiler);
178
+ this.applyAsyncSubPackagePlugin(compiler);
122
179
  if (!this.loadChunksPlugin) {
123
180
  this.loadChunksPlugin = new TaroLoadChunksPlugin_1.default({
124
181
  commonChunks: commonChunks,
@@ -135,6 +192,7 @@ class TaroMiniPlugin {
135
192
  const dependencies = this.dependencies;
136
193
  const promises = [];
137
194
  this.compileIndependentPages(compiler, compilation, dependencies, promises);
195
+ this.hooks.compileExtraEntries.call(compiler, compilation, promises);
138
196
  dependencies.forEach(dep => {
139
197
  promises.push(new Promise((resolve, reject) => {
140
198
  compilation.addEntry(this.options.sourceDir, dep, Object.assign({ name: dep.name }, dep.options), err => err ? reject(err) : resolve(null));
@@ -147,6 +205,11 @@ class TaroMiniPlugin {
147
205
  /** For Webpack compilation get factory from compilation.dependencyFactories by denpendence's constructor */
148
206
  compilation.dependencyFactories.set(EntryDependency_1.default, normalModuleFactory);
149
207
  compilation.dependencyFactories.set(TaroSingleEntryDependency_1.default, normalModuleFactory);
208
+ if (this.options.newBlended) {
209
+ normalModuleFactory.hooks.afterResolve.tap(PLUGIN_NAME, (resolveData) => {
210
+ this.hooks.afterResolveModule.call(resolveData);
211
+ });
212
+ }
150
213
  /**
151
214
  * webpack NormalModule 在 runLoaders 真正解析资源的前一刻,
152
215
  * 往 NormalModule.loaders 中插入对应的 Taro Loader
@@ -290,6 +353,10 @@ class TaroMiniPlugin {
290
353
  let source;
291
354
  const id = (0, webpack_1.getChunkIdOrName)(chunk);
292
355
  const { miniType } = entryModule;
356
+ const modifyResult = this.hooks.modifyChunkRequire.call({ source: modules, handled: false }, id, miniType);
357
+ if (modifyResult === null || modifyResult === void 0 ? void 0 : modifyResult.handled) {
358
+ return modifyResult.source;
359
+ }
293
360
  const entryChunk = [{ name: 'app' }];
294
361
  // 所有模块都依赖app.js,确保@tarojs\plugin-platform-xxx\dist\runtime.js先于@tarojs/runtime执行,避免Taro API未被初始化
295
362
  if (this.nativeComponents.has(id) || miniType === helper_1.META_TYPE.STATIC) {
@@ -298,7 +365,8 @@ class TaroMiniPlugin {
298
365
  source = (0, webpack_1.addRequireToSource)(id, modules, v);
299
366
  }
300
367
  });
301
- return source;
368
+ // 如果没有依赖需要注入,返回原始模块
369
+ return source || modules;
302
370
  }
303
371
  else if (miniType === helper_1.META_TYPE.PAGE) {
304
372
  return (0, webpack_1.addRequireToSource)(id, modules, entryChunk);
@@ -307,6 +375,23 @@ class TaroMiniPlugin {
307
375
  });
308
376
  });
309
377
  }
378
+ /**
379
+ * 初始化异步分包插件。
380
+ * MiniPlugin 仅作为桥接,具体的 babel 注入、chunk 处理和 app.json 注册由 AsyncSubPackagePlugin 承担。
381
+ */
382
+ applyAsyncSubPackagePlugin(compiler) {
383
+ if (!this.subPackageIndiePlugin)
384
+ return;
385
+ const asyncRootMap = this.subPackageIndiePlugin.getAsyncSubPackageRootMap();
386
+ if (asyncRootMap.size === 0)
387
+ return;
388
+ if (!this.asyncSubPackagePlugin) {
389
+ this.asyncSubPackagePlugin = new AsyncSubPackagePlugin_1.default(this);
390
+ }
391
+ this.asyncSubPackagePlugin.updateAsyncRootMap(asyncRootMap);
392
+ this.asyncSubPackagePlugin.updateAsyncRuntimeRoots(this.subPackageIndiePlugin.getAsyncSubPackageRuntimeRoots());
393
+ this.asyncSubPackagePlugin.apply(compiler);
394
+ }
310
395
  /**
311
396
  * 根据 webpack entry 配置获取入口文件路径
312
397
  * @returns app 入口文件路径
@@ -352,6 +437,8 @@ class TaroMiniPlugin {
352
437
  */
353
438
  run(compiler) {
354
439
  return __awaiter(this, void 0, void 0, function* () {
440
+ var _a;
441
+ (_a = this.subPackageIndiePlugin) === null || _a === void 0 ? void 0 : _a.invalidateRunCache();
355
442
  if (this.options.isBuildPlugin) {
356
443
  this.getPluginFiles();
357
444
  this.getConfigFiles(compiler);
@@ -477,12 +564,12 @@ class TaroMiniPlugin {
477
564
  }
478
565
  if (!this.options.template.isSupportRecursive) {
479
566
  pluginJSON.publicComponents = Object.assign({}, publicComponents, {
480
- [baseCompName]: baseCompName
567
+ [exports.baseCompName]: exports.baseCompName
481
568
  });
482
569
  }
483
570
  if (isUsingCustomWrapper) {
484
571
  pluginJSON.publicComponents = Object.assign({}, publicComponents, {
485
- [customWrapperName]: customWrapperName
572
+ [exports.customWrapperName]: exports.customWrapperName
486
573
  });
487
574
  }
488
575
  }
@@ -611,8 +698,11 @@ class TaroMiniPlugin {
611
698
  */
612
699
  addEntry(entryPath, entryName, entryType, options = {}) {
613
700
  let dep;
614
- if (this.dependencies.has(entryPath)) {
615
- dep = this.dependencies.get(entryPath);
701
+ // 对于 STATIC 类型(如 comp/custom-wrapper),使用 entryName 作为 key 的一部分
702
+ // 这允许同一个模板文件被多次添加为不同名称的入口
703
+ const depKey = entryType === helper_1.META_TYPE.STATIC ? `${entryPath}#${entryName}` : entryPath;
704
+ if (this.dependencies.has(depKey)) {
705
+ dep = this.dependencies.get(depKey);
616
706
  dep.name = entryName;
617
707
  dep.loc = { name: entryName };
618
708
  dep.request = entryPath;
@@ -623,7 +713,7 @@ class TaroMiniPlugin {
623
713
  else {
624
714
  dep = new TaroSingleEntryDependency_1.default(entryPath, entryName, { name: entryName }, entryType, options);
625
715
  }
626
- this.dependencies.set(entryPath, dep);
716
+ this.dependencies.set(depKey, dep);
627
717
  }
628
718
  /**
629
719
  * 在 this.dependencies 中新增或修改 app、模板组件、页面、组件等资源模块
@@ -631,10 +721,17 @@ class TaroMiniPlugin {
631
721
  addEntries() {
632
722
  const { template } = this.options;
633
723
  this.addEntry(this.appEntry, 'app', helper_1.META_TYPE.ENTRY);
634
- if (!template.isSupportRecursive) {
724
+ const entryFlags = this.hooks.modifyEntries.call({
725
+ skipRootComp: false,
726
+ skipRootWrapper: false,
727
+ });
728
+ if (!template.isSupportRecursive && !entryFlags.skipRootComp) {
635
729
  this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/comp'), 'comp', helper_1.META_TYPE.STATIC);
636
730
  }
637
- this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
731
+ if (!entryFlags.skipRootWrapper) {
732
+ this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
733
+ }
734
+ // subPackageIndie 下的 comp/custom-wrapper 统一走独立子编译器,避免被主编译的公共 chunk 共享
638
735
  this.pages.forEach(item => {
639
736
  if (item.isNative) {
640
737
  this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
@@ -664,6 +761,39 @@ class TaroMiniPlugin {
664
761
  }
665
762
  });
666
763
  }
764
+ computeForceCustomWrapperForWebpackMainComp() {
765
+ var _a;
766
+ if (this.options.template.isSupportRecursive)
767
+ return false;
768
+ const independentPaths = new Set();
769
+ this.independentPackages.forEach(({ pages }) => {
770
+ pages.forEach(p => independentPaths.add(p));
771
+ });
772
+ for (const page of this.pages) {
773
+ if (page.isNative || independentPaths.has(page.path))
774
+ continue;
775
+ const content = (_a = this.filesConfig[this.getConfigFilePath(page.name)]) === null || _a === void 0 ? void 0 : _a.content;
776
+ if (content === null || content === void 0 ? void 0 : content.forceCustomWrapper)
777
+ return true;
778
+ }
779
+ return false;
780
+ }
781
+ computeForceCustomWrapperForIndieRoot(pages) {
782
+ return (0, forceCustomWrapper_1.computeForceCustomWrapperForIndependentPackage)(pages, this.pages, this.filesConfig, (p) => this.getConfigFilePath(p));
783
+ }
784
+ applyForceCustomWrapperDefine(compiler) {
785
+ if (this.options.template.isSupportRecursive)
786
+ return;
787
+ const value = JSON.stringify(this.computeForceCustomWrapperForWebpackMainComp());
788
+ if (!this.forceCustomWrapperDefineDefinitions) {
789
+ this.forceCustomWrapperDefineDefinitions = {
790
+ TARO_FORCE_CUSTOM_WRAPPER: value
791
+ };
792
+ new compiler.webpack.DefinePlugin(this.forceCustomWrapperDefineDefinitions).apply(compiler);
793
+ return;
794
+ }
795
+ this.forceCustomWrapperDefineDefinitions.TARO_FORCE_CUSTOM_WRAPPER = value;
796
+ }
667
797
  replaceExt(file, ext) {
668
798
  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}`);
669
799
  }
@@ -823,7 +953,7 @@ class TaroMiniPlugin {
823
953
  filename: `[name]${this.options.fileType.style}`,
824
954
  chunkFilename: `[name]${this.options.fileType.style}`
825
955
  }).apply(childCompiler);
826
- new compiler.webpack.DefinePlugin(this.options.constantsReplaceList).apply(childCompiler);
956
+ new compiler.webpack.DefinePlugin(Object.assign(Object.assign({}, this.options.constantsReplaceList), { TARO_FORCE_CUSTOM_WRAPPER: JSON.stringify(this.computeForceCustomWrapperForIndieRoot(pages)) })).apply(childCompiler);
827
957
  if (compiler.options.optimization) {
828
958
  new SplitChunksPlugin({
829
959
  chunks: 'all',
@@ -962,6 +1092,12 @@ class TaroMiniPlugin {
962
1092
  usingComponents[key] = match ? `${node_path_1.default.sep}${match[0]}` : compPath;
963
1093
  }
964
1094
  }
1095
+ cloneThirdPartyComponent(thirdPartyComponents, componentName) {
1096
+ const attrs = component_1.componentConfig.thirdPartyComponents.get(componentName);
1097
+ if (!attrs || thirdPartyComponents.has(componentName))
1098
+ return;
1099
+ thirdPartyComponents.set(componentName, new Set(attrs));
1100
+ }
965
1101
  /** 生成小程序独立分包的相关文件 */
966
1102
  generateIndependentMiniFiles(compilation, compiler) {
967
1103
  return __awaiter(this, void 0, void 0, function* () {
@@ -978,24 +1114,27 @@ class TaroMiniPlugin {
978
1114
  this.generateTemplateFile(compilation, compiler, `${name}/${baseTemplateName}`, template.buildTemplate, component_1.componentConfig);
979
1115
  if (!template.isSupportRecursive) {
980
1116
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
981
- this.generateConfigFile(compilation, compiler, `${name}/${baseCompName}`, {
1117
+ const compConfig = {
982
1118
  component: true,
983
- styleIsolation: 'apply-shared',
1119
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
984
1120
  usingComponents: {
985
- [baseCompName]: `./${baseCompName}`,
986
- [customWrapperName]: `./${customWrapperName}`
1121
+ [exports.baseCompName]: `./${exports.baseCompName}`
987
1122
  }
988
- });
989
- this.generateTemplateFile(compilation, compiler, `${name}/${baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
1123
+ };
1124
+ if (isUsingCustomWrapper) {
1125
+ compConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1126
+ }
1127
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.baseCompName}`, compConfig);
1128
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
990
1129
  }
991
- this.generateConfigFile(compilation, compiler, `${name}/${customWrapperName}`, {
1130
+ this.generateConfigFile(compilation, compiler, `${name}/${exports.customWrapperName}`, {
992
1131
  component: true,
993
- styleIsolation: 'apply-shared',
1132
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
994
1133
  usingComponents: {
995
- [customWrapperName]: `./${customWrapperName}`
1134
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
996
1135
  }
997
1136
  });
998
- this.generateTemplateFile(compilation, compiler, `${name}/${customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
1137
+ this.generateTemplateFile(compilation, compiler, `${name}/${exports.customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
999
1138
  this.generateXSFile(compilation, compiler, `${name}/utils`);
1000
1139
  });
1001
1140
  this.pages.forEach(page => {
@@ -1018,14 +1157,14 @@ class TaroMiniPlugin {
1018
1157
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1019
1158
  }
1020
1159
  if (config) {
1021
- const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(baseCompName, ''))));
1022
- const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(customWrapperName, ''))));
1160
+ const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(exports.baseCompName, ''))));
1161
+ const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, independentName, this.getTargetFilePath(exports.customWrapperName, ''))));
1023
1162
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1024
1163
  if (isUsingCustomWrapper) {
1025
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1164
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1026
1165
  }
1027
1166
  if (!template.isSupportRecursive && !page.isNative) {
1028
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1167
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1029
1168
  }
1030
1169
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1031
1170
  }
@@ -1040,6 +1179,8 @@ class TaroMiniPlugin {
1040
1179
  const { modifyMiniConfigs } = combination.config;
1041
1180
  const baseTemplateName = 'base';
1042
1181
  const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
1182
+ let subPackageIndieCustomWrapperRoots = new Set();
1183
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1043
1184
  /**
1044
1185
  * 与原生小程序混写时解析模板与样式
1045
1186
  */
@@ -1059,47 +1200,55 @@ class TaroMiniPlugin {
1059
1200
  const appConfigName = node_path_1.default.basename(appConfigPath).replace(node_path_1.default.extname(appConfigPath), '');
1060
1201
  this.generateConfigFile(compilation, compiler, this.appEntry, this.filesConfig[appConfigName].content);
1061
1202
  }
1062
- if (!template.isSupportRecursive) {
1203
+ let skipRootTemplates = false;
1204
+ skipRootTemplates = this.hooks.modifySkipRootTemplates.call(skipRootTemplates);
1205
+ if (!template.isSupportRecursive && !skipRootTemplates) {
1063
1206
  // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
1064
- this.generateTemplateFile(compilation, compiler, baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1207
+ this.generateTemplateFile(compilation, compiler, exports.baseCompName, template.buildBaseComponentTemplate, this.options.fileType.templ);
1065
1208
  const baseCompConfig = {
1066
1209
  component: true,
1067
- styleIsolation: 'apply-shared',
1210
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1068
1211
  usingComponents: {
1069
- [baseCompName]: `./${baseCompName}`
1212
+ [exports.baseCompName]: `./${exports.baseCompName}`
1070
1213
  }
1071
1214
  };
1072
1215
  if (isUsingCustomWrapper) {
1073
- baseCompConfig.usingComponents[customWrapperName] = `./${customWrapperName}`;
1074
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1216
+ baseCompConfig.usingComponents[exports.customWrapperName] = `./${exports.customWrapperName}`;
1217
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1075
1218
  component: true,
1076
- styleIsolation: 'apply-shared',
1219
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1077
1220
  usingComponents: {
1078
- [baseCompName]: `./${baseCompName}`,
1079
- [customWrapperName]: `./${customWrapperName}`
1221
+ [exports.baseCompName]: `./${exports.baseCompName}`,
1222
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1080
1223
  }
1081
1224
  });
1082
1225
  }
1083
- this.generateConfigFile(compilation, compiler, baseCompName, baseCompConfig);
1226
+ this.generateConfigFile(compilation, compiler, exports.baseCompName, baseCompConfig);
1084
1227
  }
1085
- else {
1228
+ else if (!skipRootTemplates) {
1086
1229
  if (isUsingCustomWrapper) {
1087
- this.generateConfigFile(compilation, compiler, customWrapperName, {
1230
+ this.generateConfigFile(compilation, compiler, exports.customWrapperName, {
1088
1231
  component: true,
1089
- styleIsolation: 'apply-shared',
1232
+ styleIsolation: exports.STYLE_ISOLATION_APPLY_SHARED,
1090
1233
  usingComponents: {
1091
- [customWrapperName]: `./${customWrapperName}`
1234
+ [exports.customWrapperName]: `./${exports.customWrapperName}`
1092
1235
  }
1093
1236
  });
1094
1237
  }
1095
1238
  }
1096
- this.generateTemplateFile(compilation, compiler, baseTemplateName, template.buildTemplate, component_1.componentConfig);
1097
- isUsingCustomWrapper && this.generateTemplateFile(compilation, compiler, customWrapperName, template.buildCustomComponentTemplate, this.options.fileType.templ);
1098
- this.generateXSFile(compilation, compiler, 'utils');
1239
+ // 当配置了 mainPackageRoot 时,跳过根目录 base.wxml 和 utils.wxs 的生成
1240
+ if (!skipRootTemplates) {
1241
+ this.generateTemplateFile(compilation, compiler, baseTemplateName, template.buildTemplate, component_1.componentConfig);
1242
+ isUsingCustomWrapper && this.generateTemplateFile(compilation, compiler, exports.customWrapperName, template.buildCustomComponentTemplate, this.options.fileType.templ);
1243
+ this.generateXSFile(compilation, compiler, 'utils');
1244
+ }
1245
+ subPackageIndieCustomWrapperRoots = this.hooks.generateExtraFiles.call(subPackageIndieCustomWrapperRoots, compilation, compiler);
1246
+ compilation[SubPackageIndiePlugin_1.subPackageIndieCustomWrapperRootsKey] = subPackageIndieCustomWrapperRoots;
1099
1247
  this.components.forEach(component => {
1100
1248
  const importBaseTemplatePath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(component.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTemplatePath(baseTemplateName))));
1101
1249
  const config = this.filesConfig[this.getConfigFilePath(component.name)];
1102
1250
  if (config) {
1251
+ this.hooks.modifyComponentConfig.call({ config, component }, subPackageIndieCustomWrapperRoots);
1103
1252
  this.generateConfigFile(compilation, compiler, component.path, config.content);
1104
1253
  }
1105
1254
  if (!component.isNative) {
@@ -1107,31 +1256,46 @@ class TaroMiniPlugin {
1107
1256
  }
1108
1257
  });
1109
1258
  this.pages.forEach(page => {
1110
- const importBaseTemplatePath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTemplatePath(baseTemplateName))));
1259
+ let importBaseTemplatePath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTemplatePath(baseTemplateName))));
1111
1260
  const config = this.filesConfig[this.getConfigFilePath(page.name)];
1112
1261
  // pages 里面会混合独立分包的,在这里需要过滤一下,避免重复生成 assets
1113
1262
  const isIndependent = !!this.getIndependentPackage(page.path);
1114
1263
  if (isIndependent)
1115
1264
  return;
1116
1265
  // 生成页面模板需要在生成页面配置之前,因为会依赖到页面配置的部分内容
1266
+ 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, ''))));
1267
+ 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, ''))));
1268
+ let isPageRecursiveDisabled = false;
1269
+ let shouldUseCustomWrapper = isUsingCustomWrapper;
1270
+ const pageConfigContext = this.hooks.modifyPageConfig.call({
1271
+ importBaseTemplatePath,
1272
+ importBaseCompPath,
1273
+ importCustomWrapperPath,
1274
+ shouldUseCustomWrapper,
1275
+ isPageRecursiveDisabled,
1276
+ }, page, subPackageIndieCustomWrapperRoots);
1277
+ importBaseTemplatePath = pageConfigContext.importBaseTemplatePath;
1278
+ importBaseCompPath = pageConfigContext.importBaseCompPath;
1279
+ importCustomWrapperPath = pageConfigContext.importCustomWrapperPath;
1280
+ shouldUseCustomWrapper = pageConfigContext.shouldUseCustomWrapper;
1281
+ isPageRecursiveDisabled = pageConfigContext.isPageRecursiveDisabled;
1117
1282
  if (!page.isNative) {
1118
1283
  this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath, config);
1119
1284
  }
1120
1285
  if (config) {
1121
- const importBaseCompPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTargetFilePath(baseCompName, ''))));
1122
- const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(node_path_1.default.relative(page.path, node_path_1.default.join(sourceDir, isBuildPlugin ? 'plugin' : '', this.getTargetFilePath(customWrapperName, ''))));
1123
1286
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
1124
- if (isUsingCustomWrapper) {
1125
- config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
1287
+ if (shouldUseCustomWrapper) {
1288
+ config.content.usingComponents[exports.customWrapperName] = importCustomWrapperPath;
1126
1289
  }
1127
- if (!template.isSupportRecursive && !page.isNative) {
1128
- config.content.usingComponents[baseCompName] = importBaseCompPath;
1290
+ if (!template.isSupportRecursive && !page.isNative && !isPageRecursiveDisabled) {
1291
+ config.content.usingComponents[exports.baseCompName] = importBaseCompPath;
1129
1292
  }
1130
1293
  this.generateConfigFile(compilation, compiler, page.path, config.content);
1131
1294
  }
1132
1295
  });
1133
1296
  this.generateTabBarFiles(compilation, compiler);
1134
1297
  this.injectCommonStyles(compilation, compiler);
1298
+ this.hooks.afterGenerateFiles.call(compilation, compiler);
1135
1299
  if (this.themeLocation) {
1136
1300
  this.generateDarkModeFile(compilation, compiler);
1137
1301
  }
@@ -1164,12 +1328,15 @@ class TaroMiniPlugin {
1164
1328
  delete compilation.assets[assetPath];
1165
1329
  }
1166
1330
  });
1331
+ this.hooks.optimizeAssets.call(compilation);
1167
1332
  });
1168
1333
  }
1169
1334
  generateConfigFile(compilation, compiler, filePath, config) {
1170
1335
  const { RawSource } = compiler.webpack.sources;
1171
1336
  const fileConfigName = this.getConfigPath(this.getComponentName(filePath));
1172
- const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components'];
1337
+ const componentName = this.getComponentName(filePath);
1338
+ config = this.hooks.modifyConfig.call(config, componentName);
1339
+ const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components', 'forceCustomWrapper'];
1173
1340
  unofficialConfigs.forEach(item => {
1174
1341
  delete config[item];
1175
1342
  });
@@ -1315,12 +1482,21 @@ class TaroMiniPlugin {
1315
1482
  });
1316
1483
  });
1317
1484
  }
1318
- if (commons.size() > 0) {
1485
+ // 判断是否需要处理样式:有 common chunks 或者有 app.wxss(可被扩展插件修改)
1486
+ const hasAppStyle = !!assets[appStyle];
1487
+ let shouldProcessStyles = commons.size() > 0;
1488
+ if (!hasAppStyle) {
1489
+ shouldProcessStyles = false;
1490
+ }
1491
+ shouldProcessStyles = this.hooks.modifyShouldProcessStyles.call(shouldProcessStyles);
1492
+ if (shouldProcessStyles) {
1319
1493
  const APP_STYLE_NAME = 'app-origin' + styleExt;
1320
1494
  assets[APP_STYLE_NAME] = new ConcatSource(originSource);
1321
1495
  const source = new ConcatSource('');
1322
1496
  source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(APP_STYLE_NAME))};`);
1323
- source.add(commons);
1497
+ if (commons.size() > 0) {
1498
+ source.add(commons);
1499
+ }
1324
1500
  source.add('\n');
1325
1501
  assets[appStyle] = source;
1326
1502
  if (newBlended) {
@@ -1336,14 +1512,43 @@ class TaroMiniPlugin {
1336
1512
  }
1337
1513
  const source = new ConcatSource('');
1338
1514
  const originSource = assets[pageStyle];
1339
- componentCommons.forEach(item => {
1340
- source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(node_path_1.default.posix.relative(node_path_1.default.dirname(pageStyle), item)))};\n`);
1341
- });
1515
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1516
+ importStatement: '',
1517
+ shouldSkip: false,
1518
+ isMainPackageRoot: false,
1519
+ }, page);
1520
+ if (styleImportContext.shouldSkip) {
1521
+ // no-op
1522
+ }
1523
+ else if (styleImportContext.importStatement) {
1524
+ source.add(styleImportContext.importStatement);
1525
+ }
1526
+ else {
1527
+ componentCommons.forEach(item => {
1528
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(node_path_1.default.posix.relative(node_path_1.default.dirname(pageStyle), item)))};\n`);
1529
+ });
1530
+ }
1342
1531
  source.add(originSource);
1343
1532
  assets[pageStyle] = source;
1344
1533
  }
1345
1534
  else {
1346
- if (pageStyle in assets) {
1535
+ // 普通页面(非本地化组件)
1536
+ const styleImportContext = this.hooks.modifyStyleImport.call({
1537
+ importStatement: '',
1538
+ shouldSkip: false,
1539
+ isMainPackageRoot: false,
1540
+ }, page);
1541
+ if (styleImportContext.importStatement) {
1542
+ const source = new ConcatSource('');
1543
+ if (pageStyle in assets) {
1544
+ source.add(assets[pageStyle]);
1545
+ }
1546
+ const importSource = new ConcatSource('');
1547
+ importSource.add(styleImportContext.importStatement);
1548
+ importSource.add(source);
1549
+ assets[pageStyle] = importSource;
1550
+ }
1551
+ else if (pageStyle in assets) {
1347
1552
  const source = new ConcatSource('');
1348
1553
  const originSource = assets[pageStyle];
1349
1554
  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`);