@tarojs/webpack5-runner 3.7.0-alpha.0 → 3.7.0-alpha.10

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 (55) hide show
  1. package/dist/index.h5.js +5 -2
  2. package/dist/index.h5.js.map +1 -1
  3. package/dist/index.mini.js.map +1 -1
  4. package/dist/loaders/miniXScriptLoader.js.map +1 -1
  5. package/dist/plugins/BuildNativePlugin.js +32 -0
  6. package/dist/plugins/BuildNativePlugin.js.map +1 -1
  7. package/dist/plugins/H5Plugin.js +2 -7
  8. package/dist/plugins/H5Plugin.js.map +1 -1
  9. package/dist/plugins/MiniPlugin.js +348 -92
  10. package/dist/plugins/MiniPlugin.js.map +1 -1
  11. package/dist/plugins/MiniSplitChunksPlugin.js +96 -76
  12. package/dist/plugins/MiniSplitChunksPlugin.js.map +1 -1
  13. package/dist/plugins/TaroComponentsExportsPlugin.js +30 -11
  14. package/dist/plugins/TaroComponentsExportsPlugin.js.map +1 -1
  15. package/dist/plugins/TaroLoadChunksPlugin.js +2 -2
  16. package/dist/plugins/TaroLoadChunksPlugin.js.map +1 -1
  17. package/dist/plugins/TaroNormalModule.js +79 -1
  18. package/dist/plugins/TaroNormalModule.js.map +1 -1
  19. package/dist/plugins/TaroNormalModulesPlugin.js +73 -18
  20. package/dist/plugins/TaroNormalModulesPlugin.js.map +1 -1
  21. package/dist/plugins/TaroSingleEntryPlugin.js +6 -5
  22. package/dist/plugins/TaroSingleEntryPlugin.js.map +1 -1
  23. package/dist/postcss/postcss-alias.js +32 -0
  24. package/dist/postcss/postcss-alias.js.map +1 -0
  25. package/dist/postcss/postcss.h5.js +2 -1
  26. package/dist/postcss/postcss.h5.js.map +1 -1
  27. package/dist/postcss/postcss.mini.js +2 -1
  28. package/dist/postcss/postcss.mini.js.map +1 -1
  29. package/dist/prerender/prerender.js +4 -7
  30. package/dist/prerender/prerender.js.map +1 -1
  31. package/dist/utils/component.js +4 -1
  32. package/dist/utils/component.js.map +1 -1
  33. package/dist/utils/index.js.map +1 -1
  34. package/dist/webpack/BuildNativePlugin.js +3 -4
  35. package/dist/webpack/BuildNativePlugin.js.map +1 -1
  36. package/dist/webpack/Combination.js +10 -7
  37. package/dist/webpack/Combination.js.map +1 -1
  38. package/dist/webpack/H5BaseConfig.js +16 -7
  39. package/dist/webpack/H5BaseConfig.js.map +1 -1
  40. package/dist/webpack/H5Combination.js +13 -3
  41. package/dist/webpack/H5Combination.js.map +1 -1
  42. package/dist/webpack/H5WebpackModule.js +2 -1
  43. package/dist/webpack/H5WebpackModule.js.map +1 -1
  44. package/dist/webpack/H5WebpackPlugin.js.map +1 -1
  45. package/dist/webpack/MiniBaseConfig.js +18 -12
  46. package/dist/webpack/MiniBaseConfig.js.map +1 -1
  47. package/dist/webpack/MiniCombination.js +0 -1
  48. package/dist/webpack/MiniCombination.js.map +1 -1
  49. package/dist/webpack/MiniWebpackModule.js +4 -3
  50. package/dist/webpack/MiniWebpackModule.js.map +1 -1
  51. package/dist/webpack/MiniWebpackPlugin.js +3 -1
  52. package/dist/webpack/MiniWebpackPlugin.js.map +1 -1
  53. package/dist/webpack/WebpackModule.js +5 -3
  54. package/dist/webpack/WebpackModule.js.map +1 -1
  55. package/package.json +22 -21
@@ -13,17 +13,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const helper_1 = require("@tarojs/helper");
16
- const fs_extra_1 = __importDefault(require("fs-extra"));
17
16
  const loader_utils_1 = require("loader-utils");
18
17
  const path_1 = __importDefault(require("path"));
19
18
  const EntryDependency_1 = __importDefault(require("webpack/lib/dependencies/EntryDependency"));
20
19
  const TaroSingleEntryDependency_1 = __importDefault(require("../dependencies/TaroSingleEntryDependency"));
21
20
  const prerender_1 = require("../prerender/prerender");
22
21
  const component_1 = require("../utils/component");
22
+ const webpack_1 = require("../utils/webpack");
23
23
  const TaroLoadChunksPlugin_1 = __importDefault(require("./TaroLoadChunksPlugin"));
24
24
  const TaroNormalModulesPlugin_1 = __importDefault(require("./TaroNormalModulesPlugin"));
25
25
  const TaroSingleEntryPlugin_1 = __importDefault(require("./TaroSingleEntryPlugin"));
26
+ const baseCompName = 'comp';
27
+ const customWrapperName = 'custom-wrapper';
26
28
  const PLUGIN_NAME = 'TaroMiniPlugin';
29
+ const CHILD_COMPILER_TAG = 'child';
27
30
  function isLoaderExist(loaders, loaderName) {
28
31
  return loaders.some(item => item.loader === loaderName);
29
32
  }
@@ -35,6 +38,8 @@ class TaroMiniPlugin {
35
38
  /** 页面列表 */
36
39
  this.pages = new Set();
37
40
  this.components = new Set();
41
+ /** 新的混合原生编译模式 newBlended 模式下,需要单独编译成原生代码的 component 的Map */
42
+ this.nativeComponents = new Map();
38
43
  /** tabbar icon 图片路径列表 */
39
44
  this.tabBarIcons = new Set();
40
45
  this.dependencies = new Map();
@@ -81,7 +86,7 @@ class TaroMiniPlugin {
81
86
  apply(compiler) {
82
87
  this.context = compiler.context;
83
88
  this.appEntry = this.getAppEntry(compiler);
84
- const { commonChunks, addChunkPages, framework, isBuildPlugin } = this.options;
89
+ const { commonChunks, addChunkPages, framework, isBuildPlugin, newBlended, } = this.options;
85
90
  /** build mode */
86
91
  compiler.hooks.run.tapAsync(PLUGIN_NAME, this.tryAsync((compiler) => __awaiter(this, void 0, void 0, function* () {
87
92
  yield this.run(compiler);
@@ -147,6 +152,7 @@ class TaroMiniPlugin {
147
152
  config: this.appConfig,
148
153
  runtimePath: this.options.runtimePath,
149
154
  blended: this.options.blended,
155
+ newBlended: this.options.newBlended,
150
156
  pxTransformConfig
151
157
  }
152
158
  });
@@ -159,13 +165,19 @@ class TaroMiniPlugin {
159
165
  isIndependent = true;
160
166
  }
161
167
  });
162
- const loaderName = isBuildPlugin ? '@tarojs/taro-loader/lib/native-component' : (isIndependent ? '@tarojs/taro-loader/lib/independentPage' : this.pageLoaderName);
168
+ const isNewBlended = this.nativeComponents.has(module.name);
169
+ const loaderName = (isNewBlended || isBuildPlugin)
170
+ ? '@tarojs/taro-loader/lib/native-component'
171
+ : (isIndependent
172
+ ? '@tarojs/taro-loader/lib/independentPage'
173
+ : this.pageLoaderName);
163
174
  if (!isLoaderExist(module.loaders, loaderName)) {
164
175
  module.loaders.unshift({
165
176
  loader: loaderName,
166
177
  options: {
167
178
  framework,
168
179
  loaderMeta,
180
+ isNewBlended,
169
181
  name: module.name,
170
182
  prerender: this.prerenderPages.has(module.name),
171
183
  config: this.filesConfig,
@@ -192,18 +204,93 @@ class TaroMiniPlugin {
192
204
  }
193
205
  }
194
206
  });
195
- const { PROCESS_ASSETS_STAGE_ADDITIONAL } = compiler.webpack.Compilation;
207
+ const { PROCESS_ASSETS_STAGE_ADDITIONAL, PROCESS_ASSETS_STAGE_OPTIMIZE, PROCESS_ASSETS_STAGE_REPORT } = compiler.webpack.Compilation;
196
208
  compilation.hooks.processAssets.tapAsync({
197
209
  name: PLUGIN_NAME,
198
210
  stage: PROCESS_ASSETS_STAGE_ADDITIONAL
199
211
  }, this.tryAsync(() => __awaiter(this, void 0, void 0, function* () {
200
- yield this.generateMiniFiles(compilation, compiler);
212
+ // 如果是子编译器,证明是编译独立分包,进行单独的处理
213
+ if (compilation.__tag === CHILD_COMPILER_TAG) {
214
+ yield this.generateIndependentMiniFiles(compilation, compiler);
215
+ }
216
+ else {
217
+ yield this.generateMiniFiles(compilation, compiler);
218
+ }
219
+ })));
220
+ compilation.hooks.processAssets.tapAsync({
221
+ name: PLUGIN_NAME,
222
+ // 删除 assets 的相关操作放在触发时机较后的 Stage,避免过早删除出现的一些问题,#13988
223
+ // Stage 触发顺序:https://webpack.js.org/api/compilation-hooks/#list-of-asset-processing-stages
224
+ stage: PROCESS_ASSETS_STAGE_OPTIMIZE
225
+ }, this.tryAsync(() => __awaiter(this, void 0, void 0, function* () {
226
+ yield this.optimizeMiniFiles(compilation, compiler);
227
+ })));
228
+ compilation.hooks.processAssets.tapAsync({
229
+ name: PLUGIN_NAME,
230
+ // 该 stage 是最后执行的,确保 taro 暴露给用户的钩子 modifyBuildAssets 在内部处理完 assets 之后再调用
231
+ stage: PROCESS_ASSETS_STAGE_REPORT
232
+ }, this.tryAsync(() => __awaiter(this, void 0, void 0, function* () {
233
+ const { modifyBuildAssets } = this.options;
234
+ if (typeof modifyBuildAssets === 'function') {
235
+ yield modifyBuildAssets(compilation.assets, this);
236
+ }
201
237
  })));
202
238
  });
203
239
  compiler.hooks.afterEmit.tapAsync(PLUGIN_NAME, this.tryAsync((compilation) => __awaiter(this, void 0, void 0, function* () {
204
240
  yield this.addTarBarFilesToDependencies(compilation);
205
241
  })));
206
242
  new TaroNormalModulesPlugin_1.default(this.options.onParseCreateElement).apply(compiler);
243
+ newBlended && this.addLoadChunksPlugin(compiler);
244
+ }
245
+ addLoadChunksPlugin(compiler) {
246
+ const fileChunks = new Map();
247
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
248
+ compilation.hooks.afterOptimizeChunks.tap(PLUGIN_NAME, chunks => {
249
+ for (const chunk of chunks) {
250
+ const id = (0, webpack_1.getChunkIdOrName)(chunk);
251
+ if (this.options.commonChunks.includes(id))
252
+ return;
253
+ const deps = [];
254
+ for (const group of chunk.groupsIterable) {
255
+ group.chunks.forEach(chunk => {
256
+ const currentChunkId = (0, webpack_1.getChunkIdOrName)(chunk);
257
+ if (id === currentChunkId)
258
+ return;
259
+ deps.push({
260
+ name: currentChunkId
261
+ });
262
+ });
263
+ }
264
+ fileChunks.set(id, deps);
265
+ }
266
+ });
267
+ compiler.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation).render.tap(PLUGIN_NAME, (modules, { chunk }) => {
268
+ var _a;
269
+ const chunkEntryModule = (0, webpack_1.getChunkEntryModule)(compilation, chunk);
270
+ if (!chunkEntryModule)
271
+ return;
272
+ const entryModule = (_a = chunkEntryModule.rootModule) !== null && _a !== void 0 ? _a : chunkEntryModule;
273
+ // addChunkPages
274
+ if (fileChunks.size) {
275
+ let source;
276
+ const id = (0, webpack_1.getChunkIdOrName)(chunk);
277
+ const { miniType } = entryModule;
278
+ const entryChunk = [{ name: 'app' }];
279
+ // 所有模块都依赖app.js,确保@tarojs\plugin-platform-xxx\dist\runtime.js先于@tarojs/runtime执行,避免Taro API未被初始化
280
+ if (this.nativeComponents.has(id) || miniType === helper_1.META_TYPE.STATIC) {
281
+ fileChunks.forEach((v, k) => {
282
+ if (k === id) {
283
+ source = (0, webpack_1.addRequireToSource)(id, modules, v);
284
+ }
285
+ });
286
+ return source;
287
+ }
288
+ else if (miniType === helper_1.META_TYPE.PAGE) {
289
+ return (0, webpack_1.addRequireToSource)(id, modules, entryChunk);
290
+ }
291
+ }
292
+ });
293
+ });
207
294
  }
208
295
  /**
209
296
  * 根据 webpack entry 配置获取入口文件路径
@@ -332,11 +419,11 @@ class TaroMiniPlugin {
332
419
  }
333
420
  this.compileFile(item);
334
421
  if (item.isNative) {
335
- this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL);
336
- if (item.stylePath && fs_extra_1.default.existsSync(item.stylePath)) {
422
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
423
+ if (item.stylePath && helper_1.fs.existsSync(item.stylePath)) {
337
424
  this.addEntry(item.stylePath, this.getStylePath(item.name), helper_1.META_TYPE.NORMAL);
338
425
  }
339
- if (item.templatePath && fs_extra_1.default.existsSync(item.templatePath)) {
426
+ if (item.templatePath && helper_1.fs.existsSync(item.templatePath)) {
340
427
  this.addEntry(item.templatePath, this.getTemplatePath(item.name), helper_1.META_TYPE.NORMAL);
341
428
  }
342
429
  }
@@ -347,11 +434,11 @@ class TaroMiniPlugin {
347
434
  this.components.forEach(item => {
348
435
  this.compileFile(item);
349
436
  if (item.isNative) {
350
- this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL);
351
- if (item.stylePath && fs_extra_1.default.existsSync(item.stylePath)) {
437
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
438
+ if (item.stylePath && helper_1.fs.existsSync(item.stylePath)) {
352
439
  this.addEntry(item.stylePath, this.getStylePath(item.name), helper_1.META_TYPE.NORMAL);
353
440
  }
354
- if (item.templatePath && fs_extra_1.default.existsSync(item.templatePath)) {
441
+ if (item.templatePath && helper_1.fs.existsSync(item.templatePath)) {
355
442
  this.addEntry(item.templatePath, this.getTemplatePath(item.name), helper_1.META_TYPE.NORMAL);
356
443
  }
357
444
  }
@@ -366,9 +453,14 @@ class TaroMiniPlugin {
366
453
  if (main) {
367
454
  pluginJSON.main = this.getTargetFilePath(main, '.js');
368
455
  }
369
- if (publicComponents && isUsingCustomWrapper) {
456
+ if (!this.options.template.isSupportRecursive) {
370
457
  pluginJSON.publicComponents = Object.assign({}, publicComponents, {
371
- 'custom-wrapper': 'custom-wrapper'
458
+ [baseCompName]: baseCompName
459
+ });
460
+ }
461
+ if (isUsingCustomWrapper) {
462
+ pluginJSON.publicComponents = Object.assign({}, publicComponents, {
463
+ [customWrapperName]: customWrapperName
372
464
  });
373
465
  }
374
466
  }
@@ -396,6 +488,7 @@ class TaroMiniPlugin {
396
488
  */
397
489
  getPages() {
398
490
  var _a;
491
+ const { newBlended } = this.options;
399
492
  if ((0, helper_1.isEmptyObject)(this.appConfig)) {
400
493
  throw new Error('缺少 app 全局配置文件,请检查!');
401
494
  }
@@ -424,6 +517,30 @@ class TaroMiniPlugin {
424
517
  })
425
518
  ]);
426
519
  this.getSubPackages(this.appConfig);
520
+ // 新的混合原生编译模式 newBlended 下,需要收集独立编译为原生自定义组件
521
+ newBlended && this.getNativeComponent();
522
+ }
523
+ /**
524
+ * 收集需要转换为本地化组件的内容
525
+ */
526
+ getNativeComponent() {
527
+ const { frameworkExts } = this.options;
528
+ const components = this.appConfig.components || [];
529
+ components.forEach(item => {
530
+ var _a;
531
+ const pagePath = (0, helper_1.resolveMainFilePath)(path_1.default.join(this.options.sourceDir, item), frameworkExts);
532
+ const componentObj = {
533
+ name: item,
534
+ path: pagePath,
535
+ isNative: false,
536
+ };
537
+ if (!this.isWatch && ((_a = this.options.logger) === null || _a === void 0 ? void 0 : _a.quiet) === false) {
538
+ (0, helper_1.printLog)("compile" /* processTypeEnum.COMPILE */, `发现[${item}]Native组件`);
539
+ }
540
+ this.pages.add(componentObj);
541
+ // 登记需要编译成原生版本的组件
542
+ this.nativeComponents.set(item, componentObj);
543
+ });
427
544
  }
428
545
  /**
429
546
  * 读取页面及其依赖的组件的配置
@@ -443,7 +560,7 @@ class TaroMiniPlugin {
443
560
  getConfigFiles(compiler) {
444
561
  const filesConfig = this.filesConfig;
445
562
  Object.keys(filesConfig).forEach(item => {
446
- if (fs_extra_1.default.existsSync(filesConfig[item].path)) {
563
+ if (helper_1.fs.existsSync(filesConfig[item].path)) {
447
564
  this.addEntry(filesConfig[item].path, item, helper_1.META_TYPE.CONFIG);
448
565
  }
449
566
  });
@@ -490,11 +607,11 @@ class TaroMiniPlugin {
490
607
  this.addEntry(path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
491
608
  this.pages.forEach(item => {
492
609
  if (item.isNative) {
493
- this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL);
494
- if (item.stylePath && fs_extra_1.default.existsSync(item.stylePath)) {
610
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
611
+ if (item.stylePath && helper_1.fs.existsSync(item.stylePath)) {
495
612
  this.addEntry(item.stylePath, this.getStylePath(item.name), helper_1.META_TYPE.NORMAL);
496
613
  }
497
- if (item.templatePath && fs_extra_1.default.existsSync(item.templatePath)) {
614
+ if (item.templatePath && helper_1.fs.existsSync(item.templatePath)) {
498
615
  this.addEntry(item.templatePath, this.getTemplatePath(item.name), helper_1.META_TYPE.NORMAL);
499
616
  }
500
617
  }
@@ -504,11 +621,11 @@ class TaroMiniPlugin {
504
621
  });
505
622
  this.components.forEach(item => {
506
623
  if (item.isNative) {
507
- this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL);
508
- if (item.stylePath && fs_extra_1.default.existsSync(item.stylePath)) {
624
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
625
+ if (item.stylePath && helper_1.fs.existsSync(item.stylePath)) {
509
626
  this.addEntry(item.stylePath, this.getStylePath(item.name), helper_1.META_TYPE.NORMAL);
510
627
  }
511
- if (item.templatePath && fs_extra_1.default.existsSync(item.templatePath)) {
628
+ if (item.templatePath && helper_1.fs.existsSync(item.templatePath)) {
512
629
  this.addEntry(item.templatePath, this.getTemplatePath(item.name), helper_1.META_TYPE.NORMAL);
513
630
  }
514
631
  }
@@ -527,7 +644,17 @@ class TaroMiniPlugin {
527
644
  const filePath = file.path;
528
645
  const fileConfigPath = file.isNative ? this.replaceExt(filePath, '.json') : this.getConfigFilePath(filePath);
529
646
  const fileConfig = (0, helper_1.readConfig)(fileConfigPath);
647
+ const { componentGenerics } = fileConfig;
530
648
  const usingComponents = fileConfig.usingComponents;
649
+ if (this.options.isBuildPlugin && componentGenerics) {
650
+ Object.keys(componentGenerics).forEach(component => {
651
+ if (componentGenerics[component]) {
652
+ if (!component_1.componentConfig.thirdPartyComponents.has(component)) {
653
+ component_1.componentConfig.thirdPartyComponents.set(component, new Set());
654
+ }
655
+ }
656
+ });
657
+ }
531
658
  // 递归收集依赖的第三方组件
532
659
  if (usingComponents) {
533
660
  const componentNames = Object.keys(usingComponents);
@@ -539,6 +666,17 @@ class TaroMiniPlugin {
539
666
  compPath = (0, helper_1.replaceAliasPath)(filePath, compPath, alias);
540
667
  fileConfig.usingComponents[compName] = compPath;
541
668
  }
669
+ // 判断是否为第三方依赖的正则,如果 test 为 false 则为第三方依赖
670
+ const notNpmPkgReg = /^[.\\/]/;
671
+ if (!this.options.skipProcessUsingComponents
672
+ && !compPath.startsWith('plugin://')
673
+ && !notNpmPkgReg.test(compPath)) {
674
+ const tempCompPath = (0, helper_1.getNpmPackageAbsolutePath)(compPath);
675
+ if (tempCompPath) {
676
+ compPath = tempCompPath;
677
+ fileConfig.usingComponents[compName] = compPath;
678
+ }
679
+ }
542
680
  depComponents.push({
543
681
  name: compName,
544
682
  path: compPath
@@ -549,8 +687,11 @@ class TaroMiniPlugin {
549
687
  }
550
688
  depComponents.forEach(item => {
551
689
  const componentPath = (0, helper_1.resolveMainFilePath)(path_1.default.resolve(path_1.default.dirname(file.path), item.path));
552
- if (fs_extra_1.default.existsSync(componentPath) && !Array.from(this.components).some(item => item.path === componentPath)) {
690
+ if (helper_1.fs.existsSync(componentPath) && !Array.from(this.components).some(item => item.path === componentPath)) {
553
691
  const componentName = this.getComponentName(componentPath);
692
+ // newBlended 模式下,本地化组件使用Page进行处理,此处直接跳过
693
+ if (this.nativeComponents.has(componentName))
694
+ return;
554
695
  const componentTempPath = this.getTemplatePath(componentPath);
555
696
  const isNative = this.isNativePageORComponent(componentTempPath);
556
697
  const componentObj = {
@@ -677,7 +818,7 @@ class TaroMiniPlugin {
677
818
  pages.forEach(pagePath => {
678
819
  if (dependencies.has(pagePath)) {
679
820
  const dep = dependencies.get(pagePath);
680
- new TaroSingleEntryPlugin_1.default(compiler.context, dep === null || dep === void 0 ? void 0 : dep.request, dep === null || dep === void 0 ? void 0 : dep.name, dep === null || dep === void 0 ? void 0 : dep.miniType).apply(childCompiler);
821
+ new TaroSingleEntryPlugin_1.default(compiler.context, dep === null || dep === void 0 ? void 0 : dep.request, dep === null || dep === void 0 ? void 0 : dep.name, dep === null || dep === void 0 ? void 0 : dep.miniType, dep === null || dep === void 0 ? void 0 : dep.options).apply(childCompiler);
681
822
  }
682
823
  this.pages.forEach(item => {
683
824
  if (item.path === pagePath) {
@@ -698,6 +839,13 @@ class TaroMiniPlugin {
698
839
  // 添加 comp 和 custom-wrapper 组件
699
840
  new TaroSingleEntryPlugin_1.default(compiler.context, path_1.default.resolve(__dirname, '..', 'template/comp'), `${name}/comp`, helper_1.META_TYPE.STATIC).apply(childCompiler);
700
841
  new TaroSingleEntryPlugin_1.default(compiler.context, path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), `${name}/custom-wrapper`, helper_1.META_TYPE.STATIC).apply(childCompiler);
842
+ // 给每个子编译器标记上名称和 tag
843
+ // tag 用于生成模板和 config 时区别于主编译器走不同的方法
844
+ // 名称用于在生成资源时判断是否为当前子编译器的资源
845
+ childCompiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
846
+ compilation.__name = name;
847
+ compilation.__tag = CHILD_COMPILER_TAG;
848
+ });
701
849
  promises.push(new Promise((resolve, reject) => {
702
850
  childCompiler.runAsChild(err => {
703
851
  if (err) {
@@ -727,16 +875,17 @@ class TaroMiniPlugin {
727
875
  item['selectedIconPath'] && this.tabBarIcons.add(item['selectedIconPath']);
728
876
  });
729
877
  if (tabBar.custom) {
730
- const customTabBarPath = path_1.default.join(sourceDir, 'custom-tab-bar');
878
+ const isAlipay = process.env.TARO_ENV === 'alipay';
879
+ const customTabBarPath = path_1.default.join(sourceDir, isAlipay ? 'customize-tab-bar' : 'custom-tab-bar');
731
880
  const customTabBarComponentPath = (0, helper_1.resolveMainFilePath)(customTabBarPath, [...frameworkExts, ...helper_1.SCRIPT_EXT]);
732
- if (fs_extra_1.default.existsSync(customTabBarComponentPath)) {
881
+ if (helper_1.fs.existsSync(customTabBarComponentPath)) {
733
882
  const customTabBarComponentTemplPath = this.getTemplatePath(customTabBarComponentPath);
734
883
  const isNative = this.isNativePageORComponent(customTabBarComponentTemplPath);
735
884
  if (!this.isWatch && ((_a = this.options.logger) === null || _a === void 0 ? void 0 : _a.quiet) === false) {
736
885
  (0, helper_1.printLog)("compile" /* processTypeEnum.COMPILE */, '自定义 tabBar', this.getShowPath(customTabBarComponentPath));
737
886
  }
738
887
  const componentObj = {
739
- name: 'custom-tab-bar/index',
888
+ name: isAlipay ? 'customize-tab-bar/index' : 'custom-tab-bar/index',
740
889
  path: customTabBarComponentPath,
741
890
  isNative,
742
891
  stylePath: isNative ? this.getStylePath(customTabBarComponentPath) : undefined,
@@ -750,43 +899,114 @@ class TaroMiniPlugin {
750
899
  }
751
900
  /** 是否为小程序原生页面或组件 */
752
901
  isNativePageORComponent(templatePath) {
753
- return fs_extra_1.default.existsSync(templatePath);
902
+ return helper_1.fs.existsSync(templatePath);
754
903
  }
755
904
  getShowPath(filePath) {
756
905
  return filePath.replace(this.context, '').replace(/\\/g, '/').replace(/^\//, '');
757
906
  }
907
+ // 调整 config 文件中 usingComponents 的路径
908
+ // 1. 将 node_modules 调整为 npm
909
+ // 2. 将 ../../../node_modules/xxx 调整为 /npm/xxx
910
+ adjustConfigContent(config) {
911
+ const { usingComponents } = config;
912
+ if (!usingComponents || this.options.skipProcessUsingComponents)
913
+ return;
914
+ for (const [key, value] of Object.entries(usingComponents)) {
915
+ if (!value.includes(helper_1.NODE_MODULES))
916
+ return;
917
+ const match = value.replace(helper_1.NODE_MODULES, 'npm').match(/npm.*/);
918
+ usingComponents[key] = match ? `${path_1.default.sep}${match[0]}` : value;
919
+ }
920
+ }
921
+ /** 生成小程序独立分包的相关文件 */
922
+ generateIndependentMiniFiles(compilation, compiler) {
923
+ return __awaiter(this, void 0, void 0, function* () {
924
+ const { template, isBuildPlugin, sourceDir } = this.options;
925
+ const baseTemplateName = this.getIsBuildPluginPath('base', isBuildPlugin);
926
+ const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
927
+ // @ts-ignore
928
+ const childName = compilation.__name;
929
+ // 为独立分包生成 base/comp/custom-wrapper
930
+ this.independentPackages.forEach((_pages, name) => {
931
+ // independentPackages 是包含了所有 ChildCompiler 的资源,如果不是当前 ChildCompiler 的资源不做处理
932
+ if (name !== childName)
933
+ return;
934
+ this.generateTemplateFile(compilation, compiler, `${name}/${baseTemplateName}`, template.buildTemplate, component_1.componentConfig);
935
+ if (!template.isSupportRecursive) {
936
+ // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
937
+ this.generateConfigFile(compilation, compiler, `${name}/${baseCompName}`, {
938
+ component: true,
939
+ usingComponents: {
940
+ [baseCompName]: `./${baseCompName}`,
941
+ [customWrapperName]: `./${customWrapperName}`
942
+ }
943
+ });
944
+ this.generateTemplateFile(compilation, compiler, `${name}/${baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
945
+ }
946
+ this.generateConfigFile(compilation, compiler, `${name}/${customWrapperName}`, {
947
+ component: true,
948
+ usingComponents: {
949
+ [customWrapperName]: `./${customWrapperName}`
950
+ }
951
+ });
952
+ this.generateTemplateFile(compilation, compiler, `${name}/${customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
953
+ this.generateXSFile(compilation, compiler, `${name}/utils`, isBuildPlugin);
954
+ });
955
+ this.pages.forEach(page => {
956
+ let importBaseTemplatePath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, this.getTemplatePath(baseTemplateName))));
957
+ const config = this.filesConfig[this.getConfigFilePath(page.name)];
958
+ let isIndependent = false;
959
+ let independentName = '';
960
+ this.independentPackages.forEach((pages, name) => {
961
+ // independentPackages 是包含了所有 ChildCompiler 的资源,如果不是当前 ChildCompiler 的资源不做处理
962
+ if (pages.includes(page.path) && name === childName) {
963
+ isIndependent = true;
964
+ independentName = name;
965
+ importBaseTemplatePath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, name, this.getTemplatePath(baseTemplateName))));
966
+ }
967
+ });
968
+ if (!isIndependent)
969
+ return;
970
+ if (config) {
971
+ const importBaseCompPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, independentName, this.getTargetFilePath(this.getIsBuildPluginPath(baseCompName, isBuildPlugin), ''))));
972
+ const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, independentName, this.getTargetFilePath(this.getIsBuildPluginPath(customWrapperName, isBuildPlugin), ''))));
973
+ config.content.usingComponents = Object.assign({}, config.content.usingComponents);
974
+ if (isUsingCustomWrapper) {
975
+ config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
976
+ }
977
+ if (!template.isSupportRecursive && !page.isNative) {
978
+ config.content.usingComponents[baseCompName] = importBaseCompPath;
979
+ }
980
+ this.generateConfigFile(compilation, compiler, page.path, config.content);
981
+ }
982
+ if (!page.isNative) {
983
+ this.generateTemplateFile(compilation, compiler, page.path, template.buildPageTemplate, importBaseTemplatePath);
984
+ }
985
+ });
986
+ });
987
+ }
758
988
  /** 生成小程序相关文件 */
759
989
  generateMiniFiles(compilation, compiler) {
760
990
  return __awaiter(this, void 0, void 0, function* () {
761
991
  const { RawSource } = compiler.webpack.sources;
762
- const { template, modifyBuildAssets, modifyMiniConfigs, isBuildPlugin, sourceDir } = this.options;
992
+ const { template, modifyMiniConfigs, isBuildPlugin, sourceDir } = this.options;
763
993
  const baseTemplateName = this.getIsBuildPluginPath('base', isBuildPlugin);
764
- const baseCompName = 'comp';
765
- const customWrapperName = 'custom-wrapper';
766
994
  const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
767
995
  /**
768
996
  * 与原生小程序混写时解析模板与样式
769
997
  */
770
998
  compilation.getAssets().forEach(({ name: assetPath }) => {
771
999
  const styleExt = this.options.fileType.style;
772
- const templExt = this.options.fileType.templ;
773
- if (new RegExp(`(\\${styleExt}|\\${templExt})\\.js(\\.map){0,1}$`).test(assetPath)) {
774
- delete compilation.assets[assetPath];
775
- }
776
- else if (new RegExp(`${styleExt}${styleExt}$`).test(assetPath)) {
1000
+ if (new RegExp(`${styleExt}${styleExt}$`).test(assetPath)) {
777
1001
  const assetObj = compilation.assets[assetPath];
778
1002
  const newAssetPath = assetPath.replace(styleExt, '');
779
1003
  compilation.assets[newAssetPath] = assetObj;
780
- delete compilation.assets[assetPath];
781
- }
782
- if (!isUsingCustomWrapper && assetPath === 'custom-wrapper.js') {
783
- delete compilation.assets[assetPath];
784
1004
  }
785
1005
  });
786
1006
  if (typeof modifyMiniConfigs === 'function') {
787
1007
  yield modifyMiniConfigs(this.filesConfig);
788
1008
  }
789
- if (!this.options.blended && !isBuildPlugin) {
1009
+ if ((!this.options.blended || !this.options.newBlended) && !isBuildPlugin) {
790
1010
  const appConfigPath = this.getConfigFilePath(this.appEntry);
791
1011
  const appConfigName = path_1.default.basename(appConfigPath).replace(path_1.default.extname(appConfigPath), '');
792
1012
  this.generateConfigFile(compilation, compiler, this.appEntry, this.filesConfig[appConfigName].content);
@@ -801,7 +1021,7 @@ class TaroMiniPlugin {
801
1021
  }
802
1022
  };
803
1023
  if (isUsingCustomWrapper) {
804
- baseCompConfig[customWrapperName] = `./${customWrapperName}`;
1024
+ baseCompConfig.usingComponents[customWrapperName] = `./${customWrapperName}`;
805
1025
  this.generateConfigFile(compilation, compiler, this.getIsBuildPluginPath(customWrapperName, isBuildPlugin), {
806
1026
  component: true,
807
1027
  usingComponents: {
@@ -825,29 +1045,6 @@ class TaroMiniPlugin {
825
1045
  this.generateTemplateFile(compilation, compiler, baseTemplateName, template.buildTemplate, component_1.componentConfig);
826
1046
  isUsingCustomWrapper && this.generateTemplateFile(compilation, compiler, this.getIsBuildPluginPath(customWrapperName, isBuildPlugin), template.buildCustomComponentTemplate, this.options.fileType.templ);
827
1047
  this.generateXSFile(compilation, compiler, 'utils', isBuildPlugin);
828
- // 为独立分包生成 base/comp/custom-wrapper
829
- this.independentPackages.forEach((_pages, name) => {
830
- this.generateTemplateFile(compilation, compiler, `${name}/${baseTemplateName}`, template.buildTemplate, component_1.componentConfig);
831
- if (!template.isSupportRecursive) {
832
- // 如微信、QQ 不支持递归模版的小程序,需要使用自定义组件协助递归
833
- this.generateConfigFile(compilation, compiler, `${name}/${baseCompName}`, {
834
- component: true,
835
- usingComponents: {
836
- [baseCompName]: `./${baseCompName}`,
837
- [customWrapperName]: `./${customWrapperName}`
838
- }
839
- });
840
- this.generateTemplateFile(compilation, compiler, `${name}/${baseCompName}`, template.buildBaseComponentTemplate, this.options.fileType.templ);
841
- }
842
- this.generateConfigFile(compilation, compiler, `${name}/${customWrapperName}`, {
843
- component: true,
844
- usingComponents: {
845
- [customWrapperName]: `./${customWrapperName}`
846
- }
847
- });
848
- this.generateTemplateFile(compilation, compiler, `${name}/${customWrapperName}`, template.buildCustomComponentTemplate, this.options.fileType.templ);
849
- this.generateXSFile(compilation, compiler, `${name}/utils`, isBuildPlugin);
850
- });
851
1048
  this.components.forEach(component => {
852
1049
  const importBaseTemplatePath = (0, helper_1.promoteRelativePath)(path_1.default.relative(component.path, path_1.default.join(sourceDir, this.getTemplatePath(baseTemplateName))));
853
1050
  const config = this.filesConfig[this.getConfigFilePath(component.name)];
@@ -859,24 +1056,20 @@ class TaroMiniPlugin {
859
1056
  }
860
1057
  });
861
1058
  this.pages.forEach(page => {
862
- let importBaseTemplatePath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, this.getTemplatePath(baseTemplateName))));
1059
+ const importBaseTemplatePath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, this.getTemplatePath(baseTemplateName))));
863
1060
  const config = this.filesConfig[this.getConfigFilePath(page.name)];
864
1061
  let isIndependent = false;
865
- let independentName = '';
866
- this.independentPackages.forEach((pages, name) => {
1062
+ // pages 里面会混合独立分包的,在这里需要过滤一下,避免重复生成 assets
1063
+ this.independentPackages.forEach(pages => {
867
1064
  if (pages.includes(page.path)) {
868
1065
  isIndependent = true;
869
- independentName = name;
870
- importBaseTemplatePath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, name, this.getTemplatePath(baseTemplateName))));
871
1066
  }
872
1067
  });
1068
+ if (isIndependent)
1069
+ return;
873
1070
  if (config) {
874
- let importBaseCompPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, this.getTargetFilePath(this.getIsBuildPluginPath(baseCompName, isBuildPlugin), ''))));
875
- let importCustomWrapperPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, this.getTargetFilePath(this.getIsBuildPluginPath(customWrapperName, isBuildPlugin), ''))));
876
- if (isIndependent) {
877
- importBaseCompPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, independentName, this.getTargetFilePath(this.getIsBuildPluginPath(baseCompName, isBuildPlugin), ''))));
878
- importCustomWrapperPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, independentName, this.getTargetFilePath(this.getIsBuildPluginPath(customWrapperName, isBuildPlugin), ''))));
879
- }
1071
+ const importBaseCompPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, this.getTargetFilePath(this.getIsBuildPluginPath(baseCompName, isBuildPlugin), ''))));
1072
+ const importCustomWrapperPath = (0, helper_1.promoteRelativePath)(path_1.default.relative(page.path, path_1.default.join(sourceDir, this.getTargetFilePath(this.getIsBuildPluginPath(customWrapperName, isBuildPlugin), ''))));
880
1073
  config.content.usingComponents = Object.assign({}, config.content.usingComponents);
881
1074
  if (isUsingCustomWrapper) {
882
1075
  config.content.usingComponents[customWrapperName] = importCustomWrapperPath;
@@ -897,16 +1090,34 @@ class TaroMiniPlugin {
897
1090
  }
898
1091
  if (isBuildPlugin) {
899
1092
  const pluginJSONPath = path_1.default.join(sourceDir, 'plugin', 'plugin.json');
900
- if (fs_extra_1.default.existsSync(pluginJSONPath)) {
901
- const pluginJSON = fs_extra_1.default.readJSONSync(pluginJSONPath);
1093
+ if (helper_1.fs.existsSync(pluginJSONPath)) {
1094
+ const pluginJSON = helper_1.fs.readJSONSync(pluginJSONPath);
902
1095
  this.modifyPluginJSON(pluginJSON);
903
1096
  const relativePath = pluginJSONPath.replace(sourceDir, '').replace(/\\/g, '/');
904
1097
  compilation.assets[relativePath] = new RawSource(JSON.stringify(pluginJSON));
905
1098
  }
906
1099
  }
907
- if (typeof modifyBuildAssets === 'function') {
908
- yield modifyBuildAssets(compilation.assets, this);
909
- }
1100
+ });
1101
+ }
1102
+ optimizeMiniFiles(compilation, _compiler) {
1103
+ return __awaiter(this, void 0, void 0, function* () {
1104
+ const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
1105
+ /**
1106
+ * 与原生小程序混写时解析模板与样式
1107
+ */
1108
+ compilation.getAssets().forEach(({ name: assetPath }) => {
1109
+ const styleExt = this.options.fileType.style;
1110
+ const templExt = this.options.fileType.templ;
1111
+ if (new RegExp(`(\\${styleExt}|\\${templExt})\\.js(\\.map){0,1}$`).test(assetPath)) {
1112
+ delete compilation.assets[assetPath];
1113
+ }
1114
+ else if (new RegExp(`${styleExt}${styleExt}$`).test(assetPath)) {
1115
+ delete compilation.assets[assetPath];
1116
+ }
1117
+ if (!isUsingCustomWrapper && assetPath === 'custom-wrapper.js') {
1118
+ delete compilation.assets[assetPath];
1119
+ }
1120
+ });
910
1121
  });
911
1122
  }
912
1123
  generateConfigFile(compilation, compiler, filePath, config) {
@@ -916,6 +1127,7 @@ class TaroMiniPlugin {
916
1127
  unofficialConfigs.forEach(item => {
917
1128
  delete config[item];
918
1129
  });
1130
+ this.adjustConfigContent(config);
919
1131
  const fileConfigStr = JSON.stringify(config);
920
1132
  compilation.assets[fileConfigName] = new RawSource(fileConfigStr);
921
1133
  }
@@ -993,8 +1205,8 @@ class TaroMiniPlugin {
993
1205
  generateDarkModeFile(compilation, { webpack }) {
994
1206
  const { RawSource } = webpack.sources;
995
1207
  const themeLocationPath = path_1.default.resolve(this.options.sourceDir, this.themeLocation);
996
- if (fs_extra_1.default.existsSync(themeLocationPath)) {
997
- const themeLocationSource = fs_extra_1.default.readFileSync(themeLocationPath);
1208
+ if (helper_1.fs.existsSync(themeLocationPath)) {
1209
+ const themeLocationSource = helper_1.fs.readFileSync(themeLocationPath);
998
1210
  compilation.assets[this.themeLocation] = new RawSource(themeLocationSource);
999
1211
  }
1000
1212
  }
@@ -1005,8 +1217,8 @@ class TaroMiniPlugin {
1005
1217
  const { RawSource } = webpack.sources;
1006
1218
  this.tabBarIcons.forEach(icon => {
1007
1219
  const iconPath = path_1.default.resolve(this.options.sourceDir, icon);
1008
- if (fs_extra_1.default.existsSync(iconPath)) {
1009
- const iconSource = fs_extra_1.default.readFileSync(iconPath);
1220
+ if (helper_1.fs.existsSync(iconPath)) {
1221
+ const iconSource = helper_1.fs.readFileSync(iconPath);
1010
1222
  compilation.assets[icon] = new RawSource(iconSource);
1011
1223
  }
1012
1224
  });
@@ -1015,22 +1227,66 @@ class TaroMiniPlugin {
1015
1227
  * 小程序全局样式文件中引入 common chunks 中的公共样式文件
1016
1228
  */
1017
1229
  injectCommonStyles({ assets }, { webpack }) {
1018
- const { ConcatSource } = webpack.sources;
1230
+ const { newBlended } = this.options;
1231
+ const { ConcatSource, RawSource } = webpack.sources;
1019
1232
  const styleExt = this.options.fileType.style;
1020
1233
  const appStyle = `app${styleExt}`;
1021
1234
  const REG_STYLE_EXT = new RegExp(`\\.(${styleExt.replace('.', '')})(\\?.*)?$`);
1022
- if (!assets[appStyle])
1023
- return;
1024
- const originSource = assets[appStyle];
1025
- const source = new ConcatSource(originSource);
1235
+ const originSource = assets[appStyle] || new RawSource('');
1236
+ const commons = new ConcatSource('');
1237
+ const componentCommons = [];
1238
+ const independentPackageNames = [];
1239
+ this.independentPackages.forEach((_, name) => { independentPackageNames.push(name); });
1026
1240
  Object.keys(assets).forEach(assetName => {
1027
1241
  const fileName = path_1.default.basename(assetName, path_1.default.extname(assetName));
1028
- if ((helper_1.REG_STYLE.test(assetName) || REG_STYLE_EXT.test(assetName)) && this.options.commonChunks.includes(fileName)) {
1029
- source.add('\n');
1030
- source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(assetName))};`);
1031
- assets[appStyle] = source;
1242
+ if ((helper_1.REG_STYLE.test(assetName) || REG_STYLE_EXT.test(assetName))
1243
+ && this.options.commonChunks.includes(fileName)
1244
+ // app.wxss 不能引入独立分包中的 common 样式文件
1245
+ && independentPackageNames.every(name => !assetName.includes(name))) {
1246
+ commons.add('\n');
1247
+ commons.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(assetName))};`);
1248
+ componentCommons.push(assetName);
1032
1249
  }
1033
1250
  });
1251
+ if (commons.size() > 0) {
1252
+ const APP_STYLE_NAME = 'app-origin' + styleExt;
1253
+ assets[APP_STYLE_NAME] = new ConcatSource(originSource);
1254
+ const source = new ConcatSource('');
1255
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(APP_STYLE_NAME))};`);
1256
+ source.add(commons);
1257
+ source.add('\n');
1258
+ assets[appStyle] = source;
1259
+ if (newBlended) {
1260
+ // 本地化组件引入common公共样式文件
1261
+ this.pages.forEach(page => {
1262
+ if (page.isNative)
1263
+ return;
1264
+ const pageStyle = `${page.name}${styleExt}`;
1265
+ if (this.nativeComponents.has(page.name)) {
1266
+ // 本地化组件如果没有wxss则直接写入一个空的
1267
+ if (!(pageStyle in assets)) {
1268
+ assets[pageStyle] = new ConcatSource('');
1269
+ }
1270
+ const source = new ConcatSource('');
1271
+ const originSource = assets[pageStyle];
1272
+ componentCommons.forEach(item => {
1273
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(path_1.default.relative(path_1.default.dirname(pageStyle), item)))};\n`);
1274
+ });
1275
+ source.add(originSource);
1276
+ assets[pageStyle] = source;
1277
+ }
1278
+ else {
1279
+ if (pageStyle in assets) {
1280
+ const source = new ConcatSource('');
1281
+ const originSource = assets[pageStyle];
1282
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(path_1.default.relative(path_1.default.dirname(pageStyle), 'app.wxss')))};\n`);
1283
+ source.add(originSource);
1284
+ assets[pageStyle] = source;
1285
+ }
1286
+ }
1287
+ });
1288
+ }
1289
+ }
1034
1290
  }
1035
1291
  addTarBarFilesToDependencies(compilation) {
1036
1292
  const { fileDependencies, missingDependencies } = compilation;