@tarojs/webpack5-runner 4.0.1 → 4.0.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 (82) hide show
  1. package/LICENSE +8 -8
  2. package/dist/index.h5.js +9 -9
  3. package/dist/index.h5.js.map +1 -1
  4. package/dist/index.harmony.js +77 -0
  5. package/dist/index.harmony.js.map +1 -0
  6. package/dist/index.mini.js.map +1 -1
  7. package/dist/loaders/miniCompilerLoader.js +2 -2
  8. package/dist/loaders/miniCompilerLoader.js.map +1 -1
  9. package/dist/loaders/miniTemplateLoader.js.map +1 -1
  10. package/dist/loaders/miniXScriptLoader.js.map +1 -1
  11. package/dist/plugins/BuildNativePlugin.js +4 -4
  12. package/dist/plugins/BuildNativePlugin.js.map +1 -1
  13. package/dist/plugins/H5Plugin.js +6 -5
  14. package/dist/plugins/H5Plugin.js.map +1 -1
  15. package/dist/plugins/HarmonyPlugin.js +920 -0
  16. package/dist/plugins/HarmonyPlugin.js.map +1 -0
  17. package/dist/plugins/MiniCompileModePlugin.js +5 -4
  18. package/dist/plugins/MiniCompileModePlugin.js.map +1 -1
  19. package/dist/plugins/MiniPlugin.js +41 -39
  20. package/dist/plugins/MiniPlugin.js.map +1 -1
  21. package/dist/plugins/MiniSplitChunksPlugin.js +16 -16
  22. package/dist/plugins/MiniSplitChunksPlugin.js.map +1 -1
  23. package/dist/plugins/TaroComponentsExportsPlugin.js +9 -23
  24. package/dist/plugins/TaroComponentsExportsPlugin.js.map +1 -1
  25. package/dist/plugins/TaroLoadChunksPlugin.js.map +1 -1
  26. package/dist/plugins/TaroNormalModule.js.map +1 -1
  27. package/dist/plugins/TaroNormalModulesPlugin.js +11 -6
  28. package/dist/plugins/TaroNormalModulesPlugin.js.map +1 -1
  29. package/dist/plugins/WebpackBarPlugin.js.map +1 -1
  30. package/dist/postcss/postcss-alias.js.map +1 -1
  31. package/dist/postcss/postcss.h5.js +4 -5
  32. package/dist/postcss/postcss.h5.js.map +1 -1
  33. package/dist/postcss/postcss.harmony.js +96 -0
  34. package/dist/postcss/postcss.harmony.js.map +1 -0
  35. package/dist/postcss/postcss.mini.js +6 -8
  36. package/dist/postcss/postcss.mini.js.map +1 -1
  37. package/dist/prerender/prerender.js +6 -4
  38. package/dist/prerender/prerender.js.map +1 -1
  39. package/dist/template/custom-wrapper.js +2 -5
  40. package/dist/utils/app.js +9 -9
  41. package/dist/utils/app.js.map +1 -1
  42. package/dist/utils/index.js +4 -4
  43. package/dist/utils/index.js.map +1 -1
  44. package/dist/utils/logHelper.js.map +1 -1
  45. package/dist/utils/webpack.js +2 -2
  46. package/dist/utils/webpack.js.map +1 -1
  47. package/dist/webpack/BaseConfig.js +5 -5
  48. package/dist/webpack/BaseConfig.js.map +1 -1
  49. package/dist/webpack/BuildNativePlugin.js +8 -8
  50. package/dist/webpack/BuildNativePlugin.js.map +1 -1
  51. package/dist/webpack/Combination.js +6 -4
  52. package/dist/webpack/Combination.js.map +1 -1
  53. package/dist/webpack/H5BaseConfig.js +6 -7
  54. package/dist/webpack/H5BaseConfig.js.map +1 -1
  55. package/dist/webpack/H5Combination.js +14 -7
  56. package/dist/webpack/H5Combination.js.map +1 -1
  57. package/dist/webpack/H5WebpackModule.js.map +1 -1
  58. package/dist/webpack/H5WebpackPlugin.js +5 -4
  59. package/dist/webpack/H5WebpackPlugin.js.map +1 -1
  60. package/dist/webpack/HarmonyBaseConfig.js +50 -0
  61. package/dist/webpack/HarmonyBaseConfig.js.map +1 -0
  62. package/dist/webpack/HarmonyCombination.js +92 -0
  63. package/dist/webpack/HarmonyCombination.js.map +1 -0
  64. package/dist/webpack/HarmonyWebpackModule.js +183 -0
  65. package/dist/webpack/HarmonyWebpackModule.js.map +1 -0
  66. package/dist/webpack/HarmonyWebpackPlugin.js +91 -0
  67. package/dist/webpack/HarmonyWebpackPlugin.js.map +1 -0
  68. package/dist/webpack/MiniBaseConfig.js +18 -12
  69. package/dist/webpack/MiniBaseConfig.js.map +1 -1
  70. package/dist/webpack/MiniCombination.js +7 -4
  71. package/dist/webpack/MiniCombination.js.map +1 -1
  72. package/dist/webpack/MiniWebpackModule.js +27 -35
  73. package/dist/webpack/MiniWebpackModule.js.map +1 -1
  74. package/dist/webpack/MiniWebpackPlugin.js +1 -1
  75. package/dist/webpack/MiniWebpackPlugin.js.map +1 -1
  76. package/dist/webpack/WebpackModule.js +24 -11
  77. package/dist/webpack/WebpackModule.js.map +1 -1
  78. package/dist/webpack/WebpackPlugin.js +5 -5
  79. package/dist/webpack/WebpackPlugin.js.map +1 -1
  80. package/index.js +2 -0
  81. package/package.json +74 -83
  82. package/dist/template/custom-wrapper.js.map +0 -1
@@ -0,0 +1,920 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const node_path_1 = __importDefault(require("node:path"));
16
+ const helper_1 = require("@tarojs/helper");
17
+ const loader_utils_1 = require("loader-utils");
18
+ const EntryDependency_1 = __importDefault(require("webpack/lib/dependencies/EntryDependency"));
19
+ const TaroSingleEntryDependency_1 = __importDefault(require("../dependencies/TaroSingleEntryDependency"));
20
+ const component_1 = require("../utils/component");
21
+ const webpack_1 = require("../utils/webpack");
22
+ const TaroNormalModulesPlugin_1 = __importDefault(require("./TaroNormalModulesPlugin"));
23
+ const TaroSingleEntryPlugin_1 = __importDefault(require("./TaroSingleEntryPlugin"));
24
+ const PLUGIN_NAME = 'TaroHarmonyPlugin';
25
+ const CHILD_COMPILER_TAG = 'child';
26
+ function isLoaderExist(loaders, loaderName) {
27
+ return loaders.some(item => item.loader === loaderName);
28
+ }
29
+ // TODO 该插件仍在施工中,后续会逐步完善
30
+ class TaroHarmonyPlugin {
31
+ constructor(options) {
32
+ /** app、页面、组件的配置集合 */
33
+ this.filesConfig = {};
34
+ this.isWatch = false;
35
+ /** 页面列表 */
36
+ this.pages = new Set();
37
+ this.components = new Set();
38
+ this.nativeComponents = new Map();
39
+ /** tabbar icon 图片路径列表 */
40
+ this.tabBarIcons = new Set();
41
+ this.dependencies = new Map();
42
+ this.pageLoaderName = '@tarojs/taro-loader/lib/page';
43
+ this.independentPackages = new Map();
44
+ const { combination } = options;
45
+ const harmonyBuildConfig = combination.config;
46
+ this.options = {
47
+ sourceDir: combination.sourceDir,
48
+ framework: harmonyBuildConfig.framework || 'react',
49
+ frameworkExts: harmonyBuildConfig.frameworkExts || [],
50
+ runtimePath: harmonyBuildConfig.runtimePath || '',
51
+ logger: harmonyBuildConfig.logger,
52
+ fileType: harmonyBuildConfig.fileType,
53
+ combination,
54
+ commonChunks: options.commonChunks || ['runtime', 'vendors'],
55
+ constantsReplaceList: options.constantsReplaceList,
56
+ pxTransformConfig: options.pxTransformConfig,
57
+ hot: options.hot,
58
+ loaderMeta: options.loaderMeta || {},
59
+ };
60
+ }
61
+ /**
62
+ * 自动驱动 tapAsync
63
+ */
64
+ tryAsync(fn) {
65
+ return (arg, callback) => __awaiter(this, void 0, void 0, function* () {
66
+ try {
67
+ yield fn(arg);
68
+ callback();
69
+ }
70
+ catch (err) {
71
+ callback(err);
72
+ }
73
+ });
74
+ }
75
+ /**
76
+ * 插件入口
77
+ */
78
+ apply(compiler) {
79
+ this.context = compiler.context;
80
+ this.appEntry = this.getAppEntry(compiler);
81
+ const { combination, } = this.options;
82
+ const { onCompilerMake, modifyBuildAssets, onParseCreateElement, } = combination.config;
83
+ /** build mode */
84
+ compiler.hooks.run.tapAsync(PLUGIN_NAME, this.tryAsync((compiler) => __awaiter(this, void 0, void 0, function* () {
85
+ yield this.run(compiler);
86
+ })));
87
+ /** watch mode */
88
+ compiler.hooks.watchRun.tapAsync(PLUGIN_NAME, this.tryAsync((compiler) => __awaiter(this, void 0, void 0, function* () {
89
+ const changedFiles = this.getChangedFiles(compiler);
90
+ if (changedFiles && changedFiles.size > 0) {
91
+ this.isWatch = true;
92
+ }
93
+ yield this.run(compiler);
94
+ })));
95
+ /** compilation.addEntry */
96
+ compiler.hooks.make.tapAsync(PLUGIN_NAME, this.tryAsync((compilation) => __awaiter(this, void 0, void 0, function* () {
97
+ const dependencies = this.dependencies;
98
+ const promises = [];
99
+ this.compileIndependentPages(compiler, compilation, dependencies, promises);
100
+ dependencies.forEach(dep => {
101
+ promises.push(new Promise((resolve, reject) => {
102
+ compilation.addEntry(this.options.sourceDir, dep, Object.assign({ name: dep.name }, dep.options), err => err ? reject(err) : resolve(null));
103
+ }));
104
+ });
105
+ yield Promise.all(promises);
106
+ yield (onCompilerMake === null || onCompilerMake === void 0 ? void 0 : onCompilerMake(compilation, compiler, this));
107
+ })));
108
+ compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation, { normalModuleFactory }) => {
109
+ /** For Webpack compilation get factory from compilation.dependencyFactories by denpendence's constructor */
110
+ compilation.dependencyFactories.set(EntryDependency_1.default, normalModuleFactory);
111
+ compilation.dependencyFactories.set(TaroSingleEntryDependency_1.default, normalModuleFactory);
112
+ /**
113
+ * webpack NormalModule 在 runLoaders 真正解析资源的前一刻,
114
+ * 往 NormalModule.loaders 中插入对应的 Taro Loader
115
+ */
116
+ compiler.webpack.NormalModule.getCompilationHooks(compilation).loader.tap(PLUGIN_NAME, (_loaderContext, module) => {
117
+ const { framework, loaderMeta, pxTransformConfig } = this.options;
118
+ if (module.miniType === helper_1.META_TYPE.ENTRY) {
119
+ const loaderName = '@tarojs/taro-loader';
120
+ if (!isLoaderExist(module.loaders, loaderName)) {
121
+ module.loaders.unshift({
122
+ loader: loaderName,
123
+ options: {
124
+ framework,
125
+ loaderMeta,
126
+ config: this.appConfig,
127
+ runtimePath: this.options.runtimePath,
128
+ pxTransformConfig
129
+ }
130
+ });
131
+ }
132
+ }
133
+ else if (module.miniType === helper_1.META_TYPE.PAGE) {
134
+ let isIndependent = false;
135
+ this.independentPackages.forEach(pages => {
136
+ if (pages.includes(module.resource)) {
137
+ isIndependent = true;
138
+ }
139
+ });
140
+ const isNewBlended = this.nativeComponents.has(module.name);
141
+ const loaderName = isIndependent
142
+ ? '@tarojs/taro-loader/lib/independentPage'
143
+ : this.pageLoaderName;
144
+ if (!isLoaderExist(module.loaders, loaderName)) {
145
+ module.loaders.unshift({
146
+ loader: loaderName,
147
+ options: {
148
+ framework,
149
+ loaderMeta,
150
+ isNewBlended,
151
+ name: module.name,
152
+ config: this.filesConfig,
153
+ appConfig: this.appConfig,
154
+ runtimePath: this.options.runtimePath,
155
+ hot: this.options.hot
156
+ }
157
+ });
158
+ }
159
+ }
160
+ else if (module.miniType === helper_1.META_TYPE.COMPONENT) {
161
+ const loaderName = '@tarojs/taro-loader/lib/component';
162
+ if (!isLoaderExist(module.loaders, loaderName)) {
163
+ module.loaders.unshift({
164
+ loader: loaderName,
165
+ options: {
166
+ framework,
167
+ loaderMeta,
168
+ name: module.name,
169
+ runtimePath: this.options.runtimePath
170
+ }
171
+ });
172
+ }
173
+ }
174
+ });
175
+ const { PROCESS_ASSETS_STAGE_ADDITIONAL, PROCESS_ASSETS_STAGE_OPTIMIZE, PROCESS_ASSETS_STAGE_REPORT } = compiler.webpack.Compilation;
176
+ compilation.hooks.processAssets.tapAsync({
177
+ name: PLUGIN_NAME,
178
+ stage: PROCESS_ASSETS_STAGE_ADDITIONAL
179
+ }, this.tryAsync(() => __awaiter(this, void 0, void 0, function* () {
180
+ yield this.generateMiniFiles(compilation, compiler);
181
+ })));
182
+ compilation.hooks.processAssets.tapAsync({
183
+ name: PLUGIN_NAME,
184
+ // 删除 assets 的相关操作放在触发时机较后的 Stage,避免过早删除出现的一些问题,#13988
185
+ // Stage 触发顺序:https://webpack.js.org/api/compilation-hooks/#list-of-asset-processing-stages
186
+ stage: PROCESS_ASSETS_STAGE_OPTIMIZE
187
+ }, this.tryAsync(() => __awaiter(this, void 0, void 0, function* () {
188
+ yield this.optimizeMiniFiles(compilation, compiler);
189
+ })));
190
+ compilation.hooks.processAssets.tapAsync({
191
+ name: PLUGIN_NAME,
192
+ // 该 stage 是最后执行的,确保 taro 暴露给用户的钩子 modifyBuildAssets 在内部处理完 assets 之后再调用
193
+ stage: PROCESS_ASSETS_STAGE_REPORT
194
+ }, this.tryAsync(() => __awaiter(this, void 0, void 0, function* () {
195
+ if (typeof modifyBuildAssets === 'function') {
196
+ yield modifyBuildAssets(compilation.assets, this);
197
+ }
198
+ })));
199
+ });
200
+ compiler.hooks.afterEmit.tapAsync(PLUGIN_NAME, this.tryAsync((compilation) => __awaiter(this, void 0, void 0, function* () {
201
+ yield this.addTarBarFilesToDependencies(compilation);
202
+ })));
203
+ new TaroNormalModulesPlugin_1.default(onParseCreateElement).apply(compiler);
204
+ }
205
+ addLoadChunksPlugin(compiler) {
206
+ const fileChunks = new Map();
207
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
208
+ compilation.hooks.afterOptimizeChunks.tap(PLUGIN_NAME, chunks => {
209
+ for (const chunk of chunks) {
210
+ const id = (0, webpack_1.getChunkIdOrName)(chunk);
211
+ if (this.options.commonChunks.includes(id))
212
+ return;
213
+ const deps = [];
214
+ for (const group of chunk.groupsIterable) {
215
+ group.chunks.forEach(chunk => {
216
+ const currentChunkId = (0, webpack_1.getChunkIdOrName)(chunk);
217
+ if (id === currentChunkId)
218
+ return;
219
+ deps.push({
220
+ name: currentChunkId
221
+ });
222
+ });
223
+ }
224
+ fileChunks.set(id, deps);
225
+ }
226
+ });
227
+ compiler.webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(compilation).render.tap(PLUGIN_NAME, (modules, { chunk }) => {
228
+ var _a;
229
+ const chunkEntryModule = (0, webpack_1.getChunkEntryModule)(compilation, chunk);
230
+ if (!chunkEntryModule)
231
+ return;
232
+ const entryModule = (_a = chunkEntryModule.rootModule) !== null && _a !== void 0 ? _a : chunkEntryModule;
233
+ // addChunkPages
234
+ if (fileChunks.size) {
235
+ let source;
236
+ const id = (0, webpack_1.getChunkIdOrName)(chunk);
237
+ const { miniType } = entryModule;
238
+ const entryChunk = [{ name: 'app' }];
239
+ // 所有模块都依赖app.js,确保@tarojs\plugin-platform-xxx\dist\runtime.js先于@tarojs/runtime执行,避免Taro API未被初始化
240
+ if (this.nativeComponents.has(id) || miniType === helper_1.META_TYPE.STATIC) {
241
+ fileChunks.forEach((v, k) => {
242
+ if (k === id) {
243
+ source = (0, webpack_1.addRequireToSource)(id, modules, v);
244
+ }
245
+ });
246
+ return source;
247
+ }
248
+ else if (miniType === helper_1.META_TYPE.PAGE) {
249
+ return (0, webpack_1.addRequireToSource)(id, modules, entryChunk);
250
+ }
251
+ }
252
+ });
253
+ });
254
+ }
255
+ /**
256
+ * 根据 webpack entry 配置获取入口文件路径
257
+ * @returns app 入口文件路径
258
+ */
259
+ getAppEntry(compiler) {
260
+ // const originalEntry = compiler.options.entry as webpack.EntryObject
261
+ // compiler.options.entry = {}
262
+ // return path.resolve(this.context, originalEntry.app[0])
263
+ const { entry } = compiler.options;
264
+ function getEntryPath(entry) {
265
+ const app = entry.app;
266
+ if (Array.isArray(app)) {
267
+ return app[0];
268
+ }
269
+ else if (Array.isArray(app.import)) {
270
+ return app.import[0];
271
+ }
272
+ return app;
273
+ }
274
+ const appEntryPath = getEntryPath(entry);
275
+ compiler.options.entry = {};
276
+ return appEntryPath;
277
+ }
278
+ getChangedFiles(compiler) {
279
+ return compiler.modifiedFiles;
280
+ }
281
+ /**
282
+ * 分析 app 入口文件,搜集页面、组件信息,
283
+ * 往 this.dependencies 中添加资源模块
284
+ */
285
+ run(compiler) {
286
+ this.appConfig = this.getAppConfig();
287
+ this.getPages();
288
+ this.getPagesConfig();
289
+ this.getDarkMode();
290
+ this.getConfigFiles(compiler);
291
+ this.addEntries();
292
+ }
293
+ modifyPluginJSON(pluginJSON) {
294
+ const { main } = pluginJSON;
295
+ if (main) {
296
+ pluginJSON.main = this.getTargetFilePath(main, '.js');
297
+ }
298
+ }
299
+ /**
300
+ * 获取 app config 配置内容
301
+ * @returns app config 配置内容
302
+ */
303
+ getAppConfig() {
304
+ const appName = node_path_1.default.basename(this.appEntry).replace(node_path_1.default.extname(this.appEntry), '');
305
+ this.compileFile({
306
+ name: appName,
307
+ path: this.appEntry,
308
+ isNative: false
309
+ });
310
+ const fileConfig = this.filesConfig[this.getConfigFilePath(appName)];
311
+ const appConfig = fileConfig ? fileConfig.content || {} : {};
312
+ if ((0, helper_1.isEmptyObject)(appConfig)) {
313
+ throw new Error('缺少 app 全局配置文件,请检查!');
314
+ }
315
+ return appConfig;
316
+ }
317
+ /**
318
+ * 根据 app config 的 pages 配置项,收集所有页面信息,
319
+ * 包括处理分包和 tabbar
320
+ */
321
+ getPages() {
322
+ var _a;
323
+ if ((0, helper_1.isEmptyObject)(this.appConfig)) {
324
+ throw new Error('缺少 app 全局配置文件,请检查!');
325
+ }
326
+ const appPages = this.appConfig.pages;
327
+ if (!appPages || !appPages.length) {
328
+ throw new Error('全局配置缺少 pages 字段,请检查!');
329
+ }
330
+ if (!this.isWatch && ((_a = this.options.logger) === null || _a === void 0 ? void 0 : _a.quiet) === false) {
331
+ (0, helper_1.printLog)("compile" /* processTypeEnum.COMPILE */, '发现入口', this.getShowPath(this.appEntry));
332
+ }
333
+ const { frameworkExts } = this.options;
334
+ this.getTabBarFiles(this.appConfig);
335
+ this.pages = new Set([
336
+ ...appPages.map(item => {
337
+ const pagePath = (0, helper_1.resolveMainFilePath)(node_path_1.default.join(this.options.sourceDir, item), frameworkExts);
338
+ const pageTemplatePath = this.getTemplatePath(pagePath);
339
+ const isNative = this.isNativePageORComponent(pageTemplatePath);
340
+ return {
341
+ name: item,
342
+ path: pagePath,
343
+ isNative,
344
+ stylePath: isNative ? this.getStylePath(pagePath) : undefined,
345
+ templatePath: isNative ? this.getTemplatePath(pagePath) : undefined
346
+ };
347
+ })
348
+ ]);
349
+ this.getSubPackages(this.appConfig);
350
+ }
351
+ /**
352
+ * 收集需要转换为本地化组件的内容
353
+ */
354
+ getNativeComponent() {
355
+ const { frameworkExts } = this.options;
356
+ const components = this.appConfig.components || [];
357
+ components.forEach(item => {
358
+ var _a;
359
+ const pagePath = (0, helper_1.resolveMainFilePath)(node_path_1.default.join(this.options.sourceDir, item), frameworkExts);
360
+ const componentObj = {
361
+ name: item,
362
+ path: pagePath,
363
+ isNative: false,
364
+ };
365
+ if (!this.isWatch && ((_a = this.options.logger) === null || _a === void 0 ? void 0 : _a.quiet) === false) {
366
+ (0, helper_1.printLog)("compile" /* processTypeEnum.COMPILE */, `发现[${item}]Native组件`);
367
+ }
368
+ this.pages.add(componentObj);
369
+ // 登记需要编译成原生版本的组件
370
+ this.nativeComponents.set(item, componentObj);
371
+ });
372
+ }
373
+ /**
374
+ * 读取页面及其依赖的组件的配置
375
+ */
376
+ getPagesConfig() {
377
+ this.pages.forEach(page => {
378
+ var _a;
379
+ if (!this.isWatch && ((_a = this.options.logger) === null || _a === void 0 ? void 0 : _a.quiet) === false) {
380
+ (0, helper_1.printLog)("compile" /* processTypeEnum.COMPILE */, '发现页面', this.getShowPath(page.path));
381
+ }
382
+ this.compileFile(page);
383
+ });
384
+ }
385
+ /**
386
+ * 往 this.dependencies 中新增或修改所有 config 配置模块
387
+ */
388
+ getConfigFiles(compiler) {
389
+ const filesConfig = this.filesConfig;
390
+ Object.keys(filesConfig).forEach(item => {
391
+ if (helper_1.fs.existsSync(filesConfig[item].path)) {
392
+ this.addEntry(filesConfig[item].path, item, helper_1.META_TYPE.CONFIG);
393
+ }
394
+ });
395
+ // webpack createChunkAssets 前一刻,去除所有 config chunks
396
+ compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
397
+ compilation.hooks.beforeChunkAssets.tap(PLUGIN_NAME, () => {
398
+ const chunks = compilation.chunks;
399
+ const configNames = Object.keys(filesConfig);
400
+ for (const chunk of chunks) {
401
+ if (configNames.find(configName => configName === chunk.name))
402
+ chunks.delete(chunk);
403
+ }
404
+ });
405
+ });
406
+ }
407
+ /**
408
+ * 在 this.dependencies 中新增或修改模块
409
+ */
410
+ addEntry(entryPath, entryName, entryType, options = {}) {
411
+ let dep;
412
+ if (this.dependencies.has(entryPath)) {
413
+ dep = this.dependencies.get(entryPath);
414
+ dep.name = entryName;
415
+ dep.loc = { name: entryName };
416
+ dep.request = entryPath;
417
+ dep.userRequest = entryPath;
418
+ dep.miniType = entryType;
419
+ dep.options = options;
420
+ }
421
+ else {
422
+ dep = new TaroSingleEntryDependency_1.default(entryPath, entryName, { name: entryName }, entryType, options);
423
+ }
424
+ this.dependencies.set(entryPath, dep);
425
+ }
426
+ /**
427
+ * 在 this.dependencies 中新增或修改 app、模板组件、页面、组件等资源模块
428
+ */
429
+ addEntries() {
430
+ this.addEntry(this.appEntry, 'app', helper_1.META_TYPE.ENTRY);
431
+ this.addEntry(node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), 'custom-wrapper', helper_1.META_TYPE.STATIC);
432
+ this.pages.forEach(item => {
433
+ if (item.isNative) {
434
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
435
+ if (item.stylePath && helper_1.fs.existsSync(item.stylePath)) {
436
+ this.addEntry(item.stylePath, this.getStylePath(item.name), helper_1.META_TYPE.NORMAL);
437
+ }
438
+ if (item.templatePath && helper_1.fs.existsSync(item.templatePath)) {
439
+ this.addEntry(item.templatePath, this.getTemplatePath(item.name), helper_1.META_TYPE.NORMAL);
440
+ }
441
+ }
442
+ else {
443
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.PAGE);
444
+ }
445
+ });
446
+ this.components.forEach(item => {
447
+ if (item.isNative) {
448
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.NORMAL, { isNativePage: true });
449
+ if (item.stylePath && helper_1.fs.existsSync(item.stylePath)) {
450
+ this.addEntry(item.stylePath, this.getStylePath(item.name), helper_1.META_TYPE.NORMAL);
451
+ }
452
+ if (item.templatePath && helper_1.fs.existsSync(item.templatePath)) {
453
+ this.addEntry(item.templatePath, this.getTemplatePath(item.name), helper_1.META_TYPE.NORMAL);
454
+ }
455
+ }
456
+ else {
457
+ this.addEntry(item.path, item.name, helper_1.META_TYPE.COMPONENT);
458
+ }
459
+ });
460
+ }
461
+ replaceExt(file, ext) {
462
+ 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}`);
463
+ }
464
+ /**
465
+ * 读取页面、组件的配置,并递归读取依赖的组件的配置
466
+ */
467
+ compileFile(file) {
468
+ const filePath = file.path;
469
+ const fileConfigPath = file.isNative ? this.replaceExt(filePath, '.json') : this.getConfigFilePath(filePath);
470
+ const fileConfig = (0, helper_1.readConfig)(fileConfigPath, this.options.combination.config);
471
+ const usingComponents = fileConfig.usingComponents;
472
+ // 递归收集依赖的第三方组件
473
+ if (usingComponents) {
474
+ const componentNames = Object.keys(usingComponents);
475
+ const depComponents = [];
476
+ const alias = this.options.combination.config.alias;
477
+ for (const compName of componentNames) {
478
+ let compPath = usingComponents[compName];
479
+ if ((0, helper_1.isAliasPath)(compPath, alias)) {
480
+ compPath = (0, helper_1.replaceAliasPath)(filePath, compPath, alias);
481
+ fileConfig.usingComponents[compName] = compPath;
482
+ }
483
+ depComponents.push({
484
+ name: compName,
485
+ path: compPath
486
+ });
487
+ if (!component_1.componentConfig.thirdPartyComponents.has(compName) && !file.isNative) {
488
+ component_1.componentConfig.thirdPartyComponents.set(compName, new Set());
489
+ }
490
+ }
491
+ depComponents.forEach(item => {
492
+ const componentPath = (0, helper_1.resolveMainFilePath)(node_path_1.default.resolve(node_path_1.default.dirname(file.path), item.path));
493
+ if (helper_1.fs.existsSync(componentPath) && !Array.from(this.components).some(item => item.path === componentPath)) {
494
+ const componentName = this.getComponentName(componentPath);
495
+ if (this.nativeComponents.has(componentName))
496
+ return;
497
+ const componentTempPath = this.getTemplatePath(componentPath);
498
+ const isNative = this.isNativePageORComponent(componentTempPath);
499
+ const componentObj = {
500
+ name: componentName,
501
+ path: componentPath,
502
+ isNative,
503
+ stylePath: isNative ? this.getStylePath(componentPath) : undefined,
504
+ templatePath: isNative ? this.getTemplatePath(componentPath) : undefined
505
+ };
506
+ this.components.add(componentObj);
507
+ this.compileFile(componentObj);
508
+ }
509
+ });
510
+ }
511
+ this.filesConfig[this.getConfigFilePath(file.name)] = {
512
+ content: fileConfig,
513
+ path: fileConfigPath
514
+ };
515
+ }
516
+ /**
517
+ * 收集分包配置中的页面
518
+ */
519
+ getSubPackages(appConfig) {
520
+ const subPackages = appConfig.subPackages || appConfig.subpackages;
521
+ const { frameworkExts } = this.options;
522
+ if (subPackages && subPackages.length) {
523
+ subPackages.forEach(item => {
524
+ if (item.pages && item.pages.length) {
525
+ const root = item.root;
526
+ const isIndependent = !!item.independent;
527
+ if (isIndependent) {
528
+ this.independentPackages.set(root, []);
529
+ }
530
+ item.pages.forEach(page => {
531
+ let pageItem = `${root}/${page}`;
532
+ pageItem = pageItem.replace(/\/{2,}/g, '/');
533
+ let hasPageIn = false;
534
+ this.pages.forEach(({ name }) => {
535
+ if (name === pageItem) {
536
+ hasPageIn = true;
537
+ }
538
+ });
539
+ if (!hasPageIn) {
540
+ const pagePath = (0, helper_1.resolveMainFilePath)(node_path_1.default.join(this.options.sourceDir, pageItem), frameworkExts);
541
+ const templatePath = this.getTemplatePath(pagePath);
542
+ const isNative = this.isNativePageORComponent(templatePath);
543
+ if (isIndependent) {
544
+ const independentPages = this.independentPackages.get(root);
545
+ independentPages === null || independentPages === void 0 ? void 0 : independentPages.push(pagePath);
546
+ }
547
+ this.pages.add({
548
+ name: pageItem,
549
+ path: pagePath,
550
+ isNative,
551
+ stylePath: isNative ? this.getStylePath(pagePath) : undefined,
552
+ templatePath: isNative ? this.getTemplatePath(pagePath) : undefined
553
+ });
554
+ }
555
+ });
556
+ }
557
+ });
558
+ }
559
+ }
560
+ /**
561
+ * 收集 dark mode 配置中的文件
562
+ */
563
+ getDarkMode() {
564
+ const themeLocation = this.appConfig.themeLocation;
565
+ const darkMode = this.appConfig.darkmode;
566
+ if (darkMode && themeLocation && typeof themeLocation === 'string') {
567
+ this.themeLocation = themeLocation;
568
+ }
569
+ }
570
+ compileIndependentPages(compiler, compilation, dependencies, promises) {
571
+ const independentPackages = this.independentPackages;
572
+ if (independentPackages.size) {
573
+ const JsonpTemplatePlugin = require('webpack/lib/web/JsonpTemplatePlugin');
574
+ const NaturalChunkIdsPlugin = require('webpack/lib/ids/NaturalChunkIdsPlugin');
575
+ const SplitChunksPlugin = require('webpack/lib/optimize/SplitChunksPlugin');
576
+ const RuntimeChunkPlugin = require('webpack/lib/optimize/RuntimeChunkPlugin');
577
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
578
+ independentPackages.forEach((pages, name) => {
579
+ const childCompiler = compilation.createChildCompiler(PLUGIN_NAME, {
580
+ path: `${compiler.options.output.path}/${name}`,
581
+ chunkLoadingGlobal: `subpackage_${name}`
582
+ });
583
+ const compPath = node_path_1.default.resolve(__dirname, '..', 'template/comp');
584
+ childCompiler.inputFileSystem = compiler.inputFileSystem;
585
+ childCompiler.outputFileSystem = compiler.outputFileSystem;
586
+ childCompiler.context = compiler.context;
587
+ new JsonpTemplatePlugin().apply(childCompiler);
588
+ new NaturalChunkIdsPlugin().apply(childCompiler);
589
+ new MiniCssExtractPlugin({
590
+ filename: `[name]${this.options.fileType.style}`,
591
+ chunkFilename: `[name]${this.options.fileType.style}`
592
+ }).apply(childCompiler);
593
+ new compiler.webpack.DefinePlugin(this.options.constantsReplaceList).apply(childCompiler);
594
+ if (compiler.options.optimization) {
595
+ const nodeModulesDirRegx = new RegExp(helper_1.REG_NODE_MODULES_DIR);
596
+ new SplitChunksPlugin({
597
+ chunks: 'all',
598
+ maxInitialRequests: Infinity,
599
+ minSize: 0,
600
+ cacheGroups: {
601
+ common: {
602
+ name: `${name}/common`,
603
+ minChunks: 2,
604
+ priority: 1
605
+ },
606
+ vendors: {
607
+ name: `${name}/vendors`,
608
+ minChunks: 1,
609
+ test: module => {
610
+ return (nodeModulesDirRegx.test(module.resource) && module.resource.indexOf(compPath) < 0);
611
+ },
612
+ priority: 10
613
+ }
614
+ }
615
+ }).apply(childCompiler);
616
+ new RuntimeChunkPlugin({
617
+ name: `${name}/runtime`
618
+ }).apply(childCompiler);
619
+ }
620
+ const childPages = new Set();
621
+ pages.forEach(pagePath => {
622
+ if (dependencies.has(pagePath)) {
623
+ const dep = dependencies.get(pagePath);
624
+ 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);
625
+ }
626
+ this.pages.forEach(item => {
627
+ if (item.path === pagePath) {
628
+ childPages.add(item);
629
+ }
630
+ });
631
+ dependencies.delete(pagePath);
632
+ });
633
+ // 添加 comp 和 custom-wrapper 组件
634
+ new TaroSingleEntryPlugin_1.default(compiler.context, node_path_1.default.resolve(__dirname, '..', 'template/comp'), `${name}/comp`, helper_1.META_TYPE.STATIC).apply(childCompiler);
635
+ new TaroSingleEntryPlugin_1.default(compiler.context, node_path_1.default.resolve(__dirname, '..', 'template/custom-wrapper'), `${name}/custom-wrapper`, helper_1.META_TYPE.STATIC).apply(childCompiler);
636
+ // 给每个子编译器标记上名称和 tag
637
+ // tag 用于生成模板和 config 时区别于主编译器走不同的方法
638
+ // 名称用于在生成资源时判断是否为当前子编译器的资源
639
+ childCompiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
640
+ compilation.__name = name;
641
+ compilation.__tag = CHILD_COMPILER_TAG;
642
+ });
643
+ promises.push(new Promise((resolve, reject) => {
644
+ childCompiler.runAsChild(err => {
645
+ if (err) {
646
+ return reject(err);
647
+ }
648
+ resolve(null);
649
+ });
650
+ }).catch(err => console.log(err)));
651
+ });
652
+ }
653
+ }
654
+ /**
655
+ * 搜集 tabbar icon 图标路径
656
+ * 收集自定义 tabbar 组件
657
+ */
658
+ getTabBarFiles(appConfig) {
659
+ var _a;
660
+ const tabBar = appConfig.tabBar;
661
+ const { sourceDir, frameworkExts } = this.options;
662
+ if (tabBar && typeof tabBar === 'object' && !(0, helper_1.isEmptyObject)(tabBar)) {
663
+ // eslint-disable-next-line dot-notation
664
+ const list = tabBar['list'] || [];
665
+ list.forEach(item => {
666
+ // eslint-disable-next-line dot-notation
667
+ item['iconPath'] && this.tabBarIcons.add(item['iconPath']);
668
+ // eslint-disable-next-line dot-notation
669
+ item['selectedIconPath'] && this.tabBarIcons.add(item['selectedIconPath']);
670
+ });
671
+ if (tabBar.custom) {
672
+ const isAlipay = process.env.TARO_ENV === 'alipay';
673
+ const customTabBarPath = node_path_1.default.join(sourceDir, isAlipay ? 'customize-tab-bar' : 'custom-tab-bar');
674
+ const customTabBarComponentPath = (0, helper_1.resolveMainFilePath)(customTabBarPath, [...frameworkExts, ...helper_1.SCRIPT_EXT]);
675
+ if (helper_1.fs.existsSync(customTabBarComponentPath)) {
676
+ const customTabBarComponentTemplPath = this.getTemplatePath(customTabBarComponentPath);
677
+ const isNative = this.isNativePageORComponent(customTabBarComponentTemplPath);
678
+ if (!this.isWatch && ((_a = this.options.logger) === null || _a === void 0 ? void 0 : _a.quiet) === false) {
679
+ (0, helper_1.printLog)("compile" /* processTypeEnum.COMPILE */, '自定义 tabBar', this.getShowPath(customTabBarComponentPath));
680
+ }
681
+ const componentObj = {
682
+ name: isAlipay ? 'customize-tab-bar/index' : 'custom-tab-bar/index',
683
+ path: customTabBarComponentPath,
684
+ isNative,
685
+ stylePath: isNative ? this.getStylePath(customTabBarComponentPath) : undefined,
686
+ templatePath: isNative ? this.getTemplatePath(customTabBarComponentPath) : undefined
687
+ };
688
+ this.compileFile(componentObj);
689
+ this.components.add(componentObj);
690
+ }
691
+ }
692
+ }
693
+ }
694
+ /** 是否为小程序原生页面或组件 */
695
+ isNativePageORComponent(templatePath) {
696
+ return helper_1.fs.existsSync(templatePath);
697
+ }
698
+ getShowPath(filePath) {
699
+ return filePath.replace(this.context, '').replace(/\\/g, '/').replace(/^\//, '');
700
+ }
701
+ // 调整 config 文件中 usingComponents 的路径
702
+ // 1. 将 node_modules 调整为 npm
703
+ // 2. 将 ../../../node_modules/xxx 调整为 /npm/xxx
704
+ adjustConfigContent(config) {
705
+ const { usingComponents } = config;
706
+ if (!usingComponents)
707
+ return;
708
+ for (const [key, value] of Object.entries(usingComponents)) {
709
+ if (!value.includes(helper_1.NODE_MODULES))
710
+ return;
711
+ const match = value.replace(helper_1.NODE_MODULES, 'npm').match(/npm.*/);
712
+ usingComponents[key] = match ? `${node_path_1.default.sep}${match[0]}` : value;
713
+ }
714
+ }
715
+ /** 生成小程序相关文件 */
716
+ generateMiniFiles(compilation, compiler) {
717
+ return __awaiter(this, void 0, void 0, function* () {
718
+ const { combination } = this.options;
719
+ const { modifyMiniConfigs } = combination.config;
720
+ /**
721
+ * 与原生小程序混写时解析模板与样式
722
+ */
723
+ compilation.getAssets().forEach(({ name: assetPath }) => {
724
+ const styleExt = this.options.fileType.style;
725
+ if (new RegExp(`${styleExt}${styleExt}$`).test(assetPath)) {
726
+ const assetObj = compilation.assets[assetPath];
727
+ const newAssetPath = assetPath.replace(styleExt, '');
728
+ compilation.assets[newAssetPath] = assetObj;
729
+ }
730
+ });
731
+ if (typeof modifyMiniConfigs === 'function') {
732
+ yield modifyMiniConfigs(this.filesConfig);
733
+ }
734
+ const appConfigPath = this.getConfigFilePath(this.appEntry);
735
+ const appConfigName = node_path_1.default.basename(appConfigPath).replace(node_path_1.default.extname(appConfigPath), '');
736
+ this.generateConfigFile(compilation, compiler, this.appEntry, this.filesConfig[appConfigName].content);
737
+ this.components.forEach(component => {
738
+ const config = this.filesConfig[this.getConfigFilePath(component.name)];
739
+ if (config) {
740
+ this.generateConfigFile(compilation, compiler, component.path, config.content);
741
+ }
742
+ });
743
+ this.pages.forEach(page => {
744
+ const config = this.filesConfig[this.getConfigFilePath(page.name)];
745
+ let isIndependent = false;
746
+ // pages 里面会混合独立分包的,在这里需要过滤一下,避免重复生成 assets
747
+ this.independentPackages.forEach(pages => {
748
+ if (pages.includes(page.path)) {
749
+ isIndependent = true;
750
+ }
751
+ });
752
+ if (isIndependent)
753
+ return;
754
+ if (config) {
755
+ config.content.usingComponents = Object.assign({}, config.content.usingComponents);
756
+ this.generateConfigFile(compilation, compiler, page.path, config.content);
757
+ }
758
+ });
759
+ this.generateTabBarFiles(compilation, compiler);
760
+ this.injectCommonStyles(compilation, compiler);
761
+ if (this.themeLocation) {
762
+ this.generateDarkModeFile(compilation, compiler);
763
+ }
764
+ });
765
+ }
766
+ optimizeMiniFiles(compilation, _compiler) {
767
+ return __awaiter(this, void 0, void 0, function* () {
768
+ const isUsingCustomWrapper = component_1.componentConfig.thirdPartyComponents.has('custom-wrapper');
769
+ /**
770
+ * 与原生小程序混写时解析模板与样式
771
+ */
772
+ compilation.getAssets().forEach(({ name: assetPath }) => {
773
+ const styleExt = this.options.fileType.style;
774
+ const templExt = this.options.fileType.templ;
775
+ if (new RegExp(`(\\${styleExt}|\\${templExt})\\.js(\\.map){0,1}$`).test(assetPath)) {
776
+ delete compilation.assets[assetPath];
777
+ }
778
+ else if (new RegExp(`${styleExt}${styleExt}$`).test(assetPath)) {
779
+ delete compilation.assets[assetPath];
780
+ }
781
+ if (!isUsingCustomWrapper && assetPath === 'custom-wrapper.js') {
782
+ delete compilation.assets[assetPath];
783
+ }
784
+ });
785
+ });
786
+ }
787
+ generateConfigFile(compilation, compiler, filePath, config) {
788
+ const { RawSource } = compiler.webpack.sources;
789
+ const fileConfigName = this.getConfigPath(this.getComponentName(filePath));
790
+ const unofficialConfigs = ['enableShareAppMessage', 'enableShareTimeline', 'enablePageMeta', 'components'];
791
+ unofficialConfigs.forEach(item => {
792
+ delete config[item];
793
+ });
794
+ this.adjustConfigContent(config);
795
+ const fileConfigStr = JSON.stringify(config);
796
+ compilation.assets[fileConfigName] = new RawSource(fileConfigStr);
797
+ }
798
+ generateTemplateFile(compilation, compiler, filePath, templateFn, ...options) {
799
+ const { RawSource } = compiler.webpack.sources;
800
+ const templStr = templateFn(...options);
801
+ const fileTemplName = this.getTemplatePath(this.getComponentName(filePath));
802
+ compilation.assets[fileTemplName] = new RawSource(templStr);
803
+ }
804
+ getComponentName(componentPath) {
805
+ let componentName;
806
+ if (helper_1.REG_NODE_MODULES.test(componentPath)) {
807
+ const nodeModulesRegx = new RegExp(helper_1.REG_NODE_MODULES, 'gi');
808
+ componentName = componentPath.replace(this.context, '').replace(/\\/g, '/').replace(node_path_1.default.extname(componentPath), '');
809
+ componentName = componentName.replace(nodeModulesRegx, 'npm');
810
+ }
811
+ else {
812
+ componentName = componentPath.replace(this.options.sourceDir, '').replace(/\\/g, '/').replace(node_path_1.default.extname(componentPath), '');
813
+ }
814
+ return componentName.replace(/^(\/|\\)/, '');
815
+ }
816
+ getIsBuildPluginPath(filePath) {
817
+ return filePath;
818
+ }
819
+ /**
820
+ * 根据 app、页面、组件的路径获取对应的 config 配置文件的路径
821
+ * @returns config 的路径
822
+ */
823
+ getConfigFilePath(filePath) {
824
+ return (0, helper_1.resolveMainFilePath)(`${filePath.replace(node_path_1.default.extname(filePath), '')}.config`);
825
+ }
826
+ /** 处理 xml 文件后缀 */
827
+ getTemplatePath(filePath) {
828
+ return this.getTargetFilePath(filePath, this.options.fileType.templ);
829
+ }
830
+ /** 处理样式文件后缀 */
831
+ getStylePath(filePath) {
832
+ return this.getTargetFilePath(filePath, this.options.fileType.style);
833
+ }
834
+ /** 处理 config 文件后缀 */
835
+ getConfigPath(filePath) {
836
+ return this.getTargetFilePath(filePath, this.options.fileType.config);
837
+ }
838
+ /** 处理 extname */
839
+ getTargetFilePath(filePath, targetExtname) {
840
+ const extname = node_path_1.default.extname(filePath);
841
+ if (extname) {
842
+ return filePath.replace(extname, targetExtname);
843
+ }
844
+ return filePath + targetExtname;
845
+ }
846
+ /**
847
+ * 输出 themeLocation 文件
848
+ * @param compilation
849
+ */
850
+ generateDarkModeFile(compilation, { webpack }) {
851
+ const { RawSource } = webpack.sources;
852
+ const themeLocationPath = node_path_1.default.resolve(this.options.sourceDir, this.themeLocation);
853
+ if (helper_1.fs.existsSync(themeLocationPath)) {
854
+ const themeLocationSource = helper_1.fs.readFileSync(themeLocationPath);
855
+ compilation.assets[this.themeLocation] = new RawSource(themeLocationSource);
856
+ }
857
+ }
858
+ /**
859
+ * 输出 tabbar icons 文件
860
+ */
861
+ generateTabBarFiles(compilation, { webpack }) {
862
+ const { RawSource } = webpack.sources;
863
+ this.tabBarIcons.forEach(icon => {
864
+ const iconPath = node_path_1.default.resolve(this.options.sourceDir, icon);
865
+ if (helper_1.fs.existsSync(iconPath)) {
866
+ const iconSource = helper_1.fs.readFileSync(iconPath);
867
+ compilation.assets[icon] = new RawSource(iconSource);
868
+ }
869
+ });
870
+ }
871
+ /**
872
+ * 小程序全局样式文件中引入 common chunks 中的公共样式文件
873
+ */
874
+ injectCommonStyles({ assets }, { webpack }) {
875
+ const { ConcatSource, RawSource } = webpack.sources;
876
+ const styleExt = this.options.fileType.style;
877
+ const appStyle = `app${styleExt}`;
878
+ const REG_STYLE_EXT = new RegExp(`\\.(${styleExt.replace('.', '')})(\\?.*)?$`);
879
+ const originSource = assets[appStyle] || new RawSource('');
880
+ const commons = new ConcatSource('');
881
+ const componentCommons = [];
882
+ const independentPackageNames = [];
883
+ this.independentPackages.forEach((_, name) => { independentPackageNames.push(name); });
884
+ Object.keys(assets).forEach(assetName => {
885
+ const fileName = node_path_1.default.basename(assetName, node_path_1.default.extname(assetName));
886
+ if ((helper_1.REG_STYLE.test(assetName) || REG_STYLE_EXT.test(assetName)) &&
887
+ this.options.commonChunks.includes(fileName) &&
888
+ // app.wxss 不能引入独立分包中的 common 样式文件
889
+ independentPackageNames.every(name => !assetName.includes(name))) {
890
+ commons.add('\n');
891
+ commons.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(assetName))};`);
892
+ componentCommons.push(assetName);
893
+ }
894
+ });
895
+ if (commons.size() > 0) {
896
+ const APP_STYLE_NAME = 'app-origin' + styleExt;
897
+ assets[APP_STYLE_NAME] = new ConcatSource(originSource);
898
+ const source = new ConcatSource('');
899
+ source.add(`@import ${JSON.stringify((0, loader_utils_1.urlToRequest)(APP_STYLE_NAME))};`);
900
+ source.add(commons);
901
+ source.add('\n');
902
+ assets[appStyle] = source;
903
+ }
904
+ }
905
+ addTarBarFilesToDependencies(compilation) {
906
+ const { fileDependencies, missingDependencies } = compilation;
907
+ this.tabBarIcons.forEach(icon => {
908
+ if (!fileDependencies.has(icon)) {
909
+ fileDependencies.add(icon);
910
+ }
911
+ // 避免触发 watchpack 里 WatchpackFileWatcher 类的 "initial-missing" 事件中 _onRemove 逻辑,
912
+ // 它会把 tabbar icon 当做已 remove 多次触发构建
913
+ if (!missingDependencies.has(icon)) {
914
+ missingDependencies.add(icon);
915
+ }
916
+ });
917
+ }
918
+ }
919
+ exports.default = TaroHarmonyPlugin;
920
+ //# sourceMappingURL=HarmonyPlugin.js.map