@tmsfe/tmskit 0.0.66 → 0.0.68

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.
package/dist/index.cjs.js CHANGED
@@ -1548,6 +1548,52 @@ function mergeSubPackages(existingPackages, newPackages) {
1548
1548
  return resultPackages;
1549
1549
  }
1550
1550
 
1551
+ /**
1552
+ * 清理 preloadRule 中引用了不存在分包的条目
1553
+ */
1554
+ function cleanPreloadRule(appJson) {
1555
+ if (!appJson.preloadRule) return;
1556
+ const subpackages = appJson.subpackages || [];
1557
+ const existingSubpackageNames = new Set(subpackages.map(sub => sub.name).filter(Boolean));
1558
+ const existingSubpackageRoots = new Set(subpackages.map(sub => sub.root).filter(Boolean));
1559
+ Object.keys(appJson.preloadRule).forEach(pageKey => {
1560
+ const rule = appJson.preloadRule[pageKey];
1561
+ if (rule.packages) {
1562
+ rule.packages = rule.packages.filter(pkg => existingSubpackageNames.has(pkg) || existingSubpackageRoots.has(pkg));
1563
+ if (rule.packages.length === 0) {
1564
+ delete appJson.preloadRule[pageKey];
1565
+ }
1566
+ }
1567
+ });
1568
+ if (Object.keys(appJson.preloadRule).length === 0) {
1569
+ delete appJson.preloadRule;
1570
+ }
1571
+ }
1572
+
1573
+ /**
1574
+ * 清理 entranceDeclare 中引用了不存在页面的条目
1575
+ */
1576
+ function cleanEntranceDeclare(appJson) {
1577
+ // 收集所有有效页面路径(主包 pages + 分包 pages)
1578
+ const allValidPages = new Set(appJson.pages || []);
1579
+ (appJson.subpackages || []).forEach(sub => {
1580
+ (sub.pages || []).forEach(page => {
1581
+ allValidPages.add(`${sub.root}/${page}`);
1582
+ });
1583
+ });
1584
+ if (!appJson.entranceDeclare) return;
1585
+ Object.keys(appJson.entranceDeclare).forEach(key => {
1586
+ const entry = appJson.entranceDeclare[key];
1587
+ if (entry && entry.path && !allValidPages.has(entry.path)) {
1588
+ info$g(`[devStrictModulesInclude] 移除 entranceDeclare.${key},页面 ${entry.path} 不存在`);
1589
+ delete appJson.entranceDeclare[key];
1590
+ }
1591
+ });
1592
+ if (Object.keys(appJson.entranceDeclare).length === 0) {
1593
+ delete appJson.entranceDeclare;
1594
+ }
1595
+ }
1596
+
1551
1597
  /**
1552
1598
  * 动态生成编译后的app.json
1553
1599
  * @param {object} tmsConfig
@@ -1574,47 +1620,10 @@ async function buildOutputAppJson$3(tmsConfig, modules) {
1574
1620
  // 更新主包,需在subpackages处理完成后执行, pages/
1575
1621
  updateMainPackages(appJson, tmsConfig.mainPackages);
1576
1622
 
1577
- // devStrictModulesInclude 模式下,清理 preloadRule 中引用了不存在分包的条目
1578
- if (tmsConfig.devStrictModulesInclude && appJson.preloadRule) {
1579
- const existingSubpackageNames = new Set((appJson.subpackages || []).map(sub => sub.name).filter(Boolean));
1580
- const existingSubpackageRoots = new Set((appJson.subpackages || []).map(sub => sub.root).filter(Boolean));
1581
- Object.keys(appJson.preloadRule).forEach(pageKey => {
1582
- const rule = appJson.preloadRule[pageKey];
1583
- if (rule.packages) {
1584
- rule.packages = rule.packages.filter(pkg => existingSubpackageNames.has(pkg) || existingSubpackageRoots.has(pkg));
1585
- if (rule.packages.length === 0) {
1586
- delete appJson.preloadRule[pageKey];
1587
- }
1588
- }
1589
- });
1590
- if (Object.keys(appJson.preloadRule).length === 0) {
1591
- delete appJson.preloadRule;
1592
- }
1593
- }
1594
-
1595
- // devStrictModulesInclude 模式下,清理引用了不存在页面路径的字段
1623
+ // devStrictModulesInclude 模式下,清理无效引用
1596
1624
  if (tmsConfig.devStrictModulesInclude) {
1597
- // 收集所有有效页面路径(主包 pages + 分包 pages)
1598
- const allValidPages = new Set(appJson.pages || []);
1599
- (appJson.subpackages || []).forEach(sub => {
1600
- (sub.pages || []).forEach(page => {
1601
- allValidPages.add(`${sub.root}/${page}`);
1602
- });
1603
- });
1604
-
1605
- // 清理 entranceDeclare 中引用了不存在页面的条目
1606
- if (appJson.entranceDeclare) {
1607
- Object.keys(appJson.entranceDeclare).forEach(key => {
1608
- const entry = appJson.entranceDeclare[key];
1609
- if (entry && entry.path && !allValidPages.has(entry.path)) {
1610
- info$g(`[devStrictModulesInclude] 移除 entranceDeclare.${key},页面 ${entry.path} 不存在`);
1611
- delete appJson.entranceDeclare[key];
1612
- }
1613
- });
1614
- if (Object.keys(appJson.entranceDeclare).length === 0) {
1615
- delete appJson.entranceDeclare;
1616
- }
1617
- }
1625
+ cleanPreloadRule(appJson);
1626
+ cleanEntranceDeclare(appJson);
1618
1627
  }
1619
1628
 
1620
1629
  // 模板渲染:先将 app.json 转为字符串,然后通过 preprocess 渲染
@@ -2692,6 +2701,29 @@ function normalizePath(p) {
2692
2701
  return p.replace(/\\/g, '/');
2693
2702
  }
2694
2703
 
2704
+ /**
2705
+ * 将组件路径 resolve 为 dist 中的绝对路径
2706
+ */
2707
+ function resolveComponentPath(componentPath, currentFileDestPath, outputDir) {
2708
+ if (componentPath.startsWith('/')) {
2709
+ return path$8.resolve(outputDir, componentPath.slice(1));
2710
+ }
2711
+ const currentDir = path$8.dirname(currentFileDestPath);
2712
+ return path$8.resolve(currentDir, componentPath);
2713
+ }
2714
+
2715
+ /**
2716
+ * 检查组件路径是否属于某个已编译模块
2717
+ */
2718
+ function isInValidModule(relativeToOutput, validModulePaths) {
2719
+ for (const modulePath of validModulePaths) {
2720
+ if (relativeToOutput === modulePath || relativeToOutput.startsWith(`${modulePath}/`)) {
2721
+ return true;
2722
+ }
2723
+ }
2724
+ return false;
2725
+ }
2726
+
2695
2727
  /**
2696
2728
  * 判断组件路径是否应该被移除
2697
2729
  * @param {string} componentPath usingComponents 中的路径
@@ -2711,39 +2743,24 @@ function shouldRemoveComponent(componentPath, currentFileDestPath, outputDir, mo
2711
2743
  if (!componentPath.startsWith('.') && !componentPath.startsWith('/')) {
2712
2744
  return false;
2713
2745
  }
2714
-
2715
- // 统一计算组件在 dist 中的绝对路径
2716
- let resolvedComponentPath;
2717
- if (componentPath.startsWith('/')) {
2718
- // 小程序绝对路径(如 /modules/xxx),相对于 dist 根目录
2719
- resolvedComponentPath = path$8.resolve(outputDir, componentPath.slice(1));
2720
- } else {
2721
- // 相对路径,相对于当前文件在 dist 中的位置
2722
- const currentDir = path$8.dirname(currentFileDestPath);
2723
- resolvedComponentPath = path$8.resolve(currentDir, componentPath);
2724
- }
2746
+ const resolvedPath = resolveComponentPath(componentPath, currentFileDestPath, outputDir);
2725
2747
 
2726
2748
  // 优先判断:组件是否在当前模块的输出目录内
2727
- const relativeToModule = normalizePath(path$8.relative(moduleDestPath, resolvedComponentPath));
2749
+ const relativeToModule = normalizePath(path$8.relative(moduleDestPath, resolvedPath));
2728
2750
  if (!relativeToModule.startsWith('..')) {
2729
2751
  return false;
2730
2752
  }
2731
2753
 
2732
2754
  // 组件在当前模块外,检查是否属于其他已编译模块
2733
- const relativeToOutput = normalizePath(path$8.relative(outputDir, resolvedComponentPath));
2755
+ const relativeToOutput = normalizePath(path$8.relative(outputDir, resolvedPath));
2734
2756
 
2735
2757
  // 路径离开了 outputDir(以 .. 开头),保留不处理
2736
2758
  if (relativeToOutput.startsWith('..')) {
2737
2759
  return false;
2738
2760
  }
2739
- for (const modulePath of validModulePaths) {
2740
- if (relativeToOutput === modulePath || relativeToOutput.startsWith(modulePath + '/')) {
2741
- return false;
2742
- }
2743
- }
2744
2761
 
2745
2762
  // 不属于任何已编译模块 → 移除
2746
- return true;
2763
+ return !isInValidModule(relativeToOutput, validModulePaths);
2747
2764
  }
2748
2765
 
2749
2766
  /**
@@ -2776,10 +2793,49 @@ function getValidModulePaths(tmsConfig) {
2776
2793
  }
2777
2794
  }
2778
2795
  });
2796
+
2797
+ // eslint-disable-next-line no-param-reassign
2779
2798
  tmsConfig._validModulePaths = paths;
2780
2799
  return paths;
2781
2800
  }
2782
2801
 
2802
+ /**
2803
+ * 处理单个 JSON 文件,移除无效组件引用
2804
+ */
2805
+ function processJsonFile(file, moduleDestPath, moduleFromPath, outputDir, validModulePaths) {
2806
+ let json;
2807
+ try {
2808
+ json = JSON.parse(String(file.contents));
2809
+ } catch (e) {
2810
+ return file;
2811
+ }
2812
+ if (!json.usingComponents || typeof json.usingComponents !== 'object') {
2813
+ return file;
2814
+ }
2815
+ const currentFileSrcPath = file.history[0] || file.path;
2816
+ const relativeToModuleSrc = path$8.relative(moduleFromPath, currentFileSrcPath);
2817
+ const currentFileDestPath = path$8.join(moduleDestPath, relativeToModuleSrc);
2818
+ const keysToRemove = [];
2819
+ Object.keys(json.usingComponents).forEach(componentKey => {
2820
+ const componentPath = json.usingComponents[componentKey];
2821
+ if (shouldRemoveComponent(componentPath, currentFileDestPath, outputDir, moduleDestPath, validModulePaths)) {
2822
+ keysToRemove.push(componentKey);
2823
+ }
2824
+ });
2825
+ if (keysToRemove.length > 0) {
2826
+ keysToRemove.forEach(key => {
2827
+ info$c(`[strictModulesFilter] 移除 ${path$8.basename(currentFileSrcPath)} 中的组件引用: ${key} -> ${json.usingComponents[key]}`);
2828
+ delete json.usingComponents[key];
2829
+ if (json.componentPlaceholder && json.componentPlaceholder[key]) {
2830
+ delete json.componentPlaceholder[key];
2831
+ }
2832
+ });
2833
+ // eslint-disable-next-line no-param-reassign
2834
+ file.contents = Buffer.from(JSON.stringify(json, null, 2));
2835
+ }
2836
+ return file;
2837
+ }
2838
+
2783
2839
  /**
2784
2840
  * 严格模块过滤 gulp 插件
2785
2841
  * @param {Object} tmsConfig 配置对象
@@ -2787,7 +2843,6 @@ function getValidModulePaths(tmsConfig) {
2787
2843
  * @returns {Object} through2 转换流
2788
2844
  */
2789
2845
  function strictModulesFilter$1(tmsConfig, module) {
2790
- // 不在严格模式下直接透传
2791
2846
  if (!tmsConfig.devStrictModulesInclude) {
2792
2847
  return through$2.obj();
2793
2848
  }
@@ -2799,57 +2854,13 @@ function strictModulesFilter$1(tmsConfig, module) {
2799
2854
  this.push(file);
2800
2855
  return cb();
2801
2856
  }
2802
-
2803
- // 自定义模块(如 watchExtendFiles)或根目录文件不处理
2804
- if (module.custom || !moduleDestPath || !moduleFromPath) {
2805
- this.push(file);
2806
- return cb();
2807
- }
2808
-
2809
- // 根目录编译任务(from === outputDir 的父目录)不处理
2810
- if (moduleDestPath === outputDir) {
2811
- this.push(file);
2812
- return cb();
2813
- }
2814
- let json;
2815
- try {
2816
- json = JSON.parse(String(file.contents));
2817
- } catch (e) {
2818
- this.push(file);
2819
- return cb();
2820
- }
2821
- if (!json.usingComponents || typeof json.usingComponents !== 'object') {
2857
+ if (module.custom || !moduleDestPath || !moduleFromPath || moduleDestPath === outputDir) {
2822
2858
  this.push(file);
2823
2859
  return cb();
2824
2860
  }
2825
-
2826
- // 计算当前文件的编译输出路径
2827
- const currentFileSrcPath = file.history[0] || file.path;
2828
- const relativeToModuleSrc = path$8.relative(moduleFromPath, currentFileSrcPath);
2829
- const currentFileDestPath = path$8.join(moduleDestPath, relativeToModuleSrc);
2830
-
2831
- // 延迟获取有效模块路径集合(首次文件处理时计算并缓存)
2832
2861
  const validModulePaths = getValidModulePaths(tmsConfig);
2833
- const keysToRemove = [];
2834
- Object.keys(json.usingComponents).forEach(componentKey => {
2835
- const componentPath = json.usingComponents[componentKey];
2836
- if (shouldRemoveComponent(componentPath, currentFileDestPath, outputDir, moduleDestPath, validModulePaths)) {
2837
- keysToRemove.push(componentKey);
2838
- }
2839
- });
2840
- if (keysToRemove.length > 0) {
2841
- keysToRemove.forEach(key => {
2842
- info$c(`[strictModulesFilter] 移除 ${path$8.basename(currentFileSrcPath)} 中的组件引用: ${key} -> ${json.usingComponents[key]}`);
2843
- delete json.usingComponents[key];
2844
- // 同步清理 componentPlaceholder
2845
- if (json.componentPlaceholder && json.componentPlaceholder[key]) {
2846
- delete json.componentPlaceholder[key];
2847
- }
2848
- });
2849
- file.contents = Buffer.from(JSON.stringify(json, null, 2));
2850
- }
2851
- this.push(file);
2852
- cb();
2862
+ this.push(processJsonFile(file, moduleDestPath, moduleFromPath, outputDir, validModulePaths));
2863
+ return cb();
2853
2864
  });
2854
2865
  }
2855
2866
  var strictModulesFilter_1 = {
@@ -4450,7 +4461,7 @@ var entry = [{
4450
4461
 
4451
4462
  var require$$12 = {
4452
4463
  name: "@tmsfe/tmskit",
4453
- version: "0.0.66",
4464
+ version: "0.0.68",
4454
4465
  description: "tmskit",
4455
4466
  main: "dist/index.cjs",
4456
4467
  bin: {
@@ -4509,7 +4520,7 @@ var require$$12 = {
4509
4520
  lodash: "^4.17.21",
4510
4521
  metalsmith: "^2.3.0",
4511
4522
  minimatch: "^5.1.0",
4512
- "miniprogram-ci": "2.1.40",
4523
+ "miniprogram-ci": "2.1.41",
4513
4524
  moment: "^2.29.2",
4514
4525
  "object-assign": "^4.0.1",
4515
4526
  ora: "^5.4.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmsfe/tmskit",
3
- "version": "0.0.66",
3
+ "version": "0.0.68",
4
4
  "description": "tmskit",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {
@@ -59,7 +59,7 @@
59
59
  "lodash": "^4.17.21",
60
60
  "metalsmith": "^2.3.0",
61
61
  "minimatch": "^5.1.0",
62
- "miniprogram-ci": "2.1.40",
62
+ "miniprogram-ci": "2.1.41",
63
63
  "moment": "^2.29.2",
64
64
  "object-assign": "^4.0.1",
65
65
  "ora": "^5.4.1",
@@ -19,6 +19,29 @@ function normalizePath(p) {
19
19
  return p.replace(/\\/g, '/');
20
20
  }
21
21
 
22
+ /**
23
+ * 将组件路径 resolve 为 dist 中的绝对路径
24
+ */
25
+ function resolveComponentPath(componentPath, currentFileDestPath, outputDir) {
26
+ if (componentPath.startsWith('/')) {
27
+ return path.resolve(outputDir, componentPath.slice(1));
28
+ }
29
+ const currentDir = path.dirname(currentFileDestPath);
30
+ return path.resolve(currentDir, componentPath);
31
+ }
32
+
33
+ /**
34
+ * 检查组件路径是否属于某个已编译模块
35
+ */
36
+ function isInValidModule(relativeToOutput, validModulePaths) {
37
+ for (const modulePath of validModulePaths) {
38
+ if (relativeToOutput === modulePath || relativeToOutput.startsWith(`${modulePath}/`)) {
39
+ return true;
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+
22
45
  /**
23
46
  * 判断组件路径是否应该被移除
24
47
  * @param {string} componentPath usingComponents 中的路径
@@ -39,39 +62,24 @@ function shouldRemoveComponent(componentPath, currentFileDestPath, outputDir, mo
39
62
  return false;
40
63
  }
41
64
 
42
- // 统一计算组件在 dist 中的绝对路径
43
- let resolvedComponentPath;
44
- if (componentPath.startsWith('/')) {
45
- // 小程序绝对路径(如 /modules/xxx),相对于 dist 根目录
46
- resolvedComponentPath = path.resolve(outputDir, componentPath.slice(1));
47
- } else {
48
- // 相对路径,相对于当前文件在 dist 中的位置
49
- const currentDir = path.dirname(currentFileDestPath);
50
- resolvedComponentPath = path.resolve(currentDir, componentPath);
51
- }
65
+ const resolvedPath = resolveComponentPath(componentPath, currentFileDestPath, outputDir);
52
66
 
53
67
  // 优先判断:组件是否在当前模块的输出目录内
54
- const relativeToModule = normalizePath(path.relative(moduleDestPath, resolvedComponentPath));
68
+ const relativeToModule = normalizePath(path.relative(moduleDestPath, resolvedPath));
55
69
  if (!relativeToModule.startsWith('..')) {
56
70
  return false;
57
71
  }
58
72
 
59
73
  // 组件在当前模块外,检查是否属于其他已编译模块
60
- const relativeToOutput = normalizePath(path.relative(outputDir, resolvedComponentPath));
74
+ const relativeToOutput = normalizePath(path.relative(outputDir, resolvedPath));
61
75
 
62
76
  // 路径离开了 outputDir(以 .. 开头),保留不处理
63
77
  if (relativeToOutput.startsWith('..')) {
64
78
  return false;
65
79
  }
66
80
 
67
- for (const modulePath of validModulePaths) {
68
- if (relativeToOutput === modulePath || relativeToOutput.startsWith(modulePath + '/')) {
69
- return false;
70
- }
71
- }
72
-
73
81
  // 不属于任何已编译模块 → 移除
74
- return true;
82
+ return !isInValidModule(relativeToOutput, validModulePaths);
75
83
  }
76
84
 
77
85
  /**
@@ -107,10 +115,53 @@ function getValidModulePaths(tmsConfig) {
107
115
  }
108
116
  });
109
117
 
118
+ // eslint-disable-next-line no-param-reassign
110
119
  tmsConfig._validModulePaths = paths;
111
120
  return paths;
112
121
  }
113
122
 
123
+ /**
124
+ * 处理单个 JSON 文件,移除无效组件引用
125
+ */
126
+ function processJsonFile(file, moduleDestPath, moduleFromPath, outputDir, validModulePaths) {
127
+ let json;
128
+ try {
129
+ json = JSON.parse(String(file.contents));
130
+ } catch (e) {
131
+ return file;
132
+ }
133
+
134
+ if (!json.usingComponents || typeof json.usingComponents !== 'object') {
135
+ return file;
136
+ }
137
+
138
+ const currentFileSrcPath = file.history[0] || file.path;
139
+ const relativeToModuleSrc = path.relative(moduleFromPath, currentFileSrcPath);
140
+ const currentFileDestPath = path.join(moduleDestPath, relativeToModuleSrc);
141
+
142
+ const keysToRemove = [];
143
+ Object.keys(json.usingComponents).forEach((componentKey) => {
144
+ const componentPath = json.usingComponents[componentKey];
145
+ if (shouldRemoveComponent(componentPath, currentFileDestPath, outputDir, moduleDestPath, validModulePaths)) {
146
+ keysToRemove.push(componentKey);
147
+ }
148
+ });
149
+
150
+ if (keysToRemove.length > 0) {
151
+ keysToRemove.forEach((key) => {
152
+ info(`[strictModulesFilter] 移除 ${path.basename(currentFileSrcPath)} 中的组件引用: ${key} -> ${json.usingComponents[key]}`);
153
+ delete json.usingComponents[key];
154
+ if (json.componentPlaceholder && json.componentPlaceholder[key]) {
155
+ delete json.componentPlaceholder[key];
156
+ }
157
+ });
158
+ // eslint-disable-next-line no-param-reassign
159
+ file.contents = Buffer.from(JSON.stringify(json, null, 2));
160
+ }
161
+
162
+ return file;
163
+ }
164
+
114
165
  /**
115
166
  * 严格模块过滤 gulp 插件
116
167
  * @param {Object} tmsConfig 配置对象
@@ -118,7 +169,6 @@ function getValidModulePaths(tmsConfig) {
118
169
  * @returns {Object} through2 转换流
119
170
  */
120
171
  function strictModulesFilter(tmsConfig, module) {
121
- // 不在严格模式下直接透传
122
172
  if (!tmsConfig.devStrictModulesInclude) {
123
173
  return through.obj();
124
174
  }
@@ -133,62 +183,14 @@ function strictModulesFilter(tmsConfig, module) {
133
183
  return cb();
134
184
  }
135
185
 
136
- // 自定义模块(如 watchExtendFiles)或根目录文件不处理
137
- if (module.custom || !moduleDestPath || !moduleFromPath) {
138
- this.push(file);
139
- return cb();
140
- }
141
-
142
- // 根目录编译任务(from === outputDir 的父目录)不处理
143
- if (moduleDestPath === outputDir) {
144
- this.push(file);
145
- return cb();
146
- }
147
-
148
- let json;
149
- try {
150
- json = JSON.parse(String(file.contents));
151
- } catch (e) {
186
+ if (module.custom || !moduleDestPath || !moduleFromPath || moduleDestPath === outputDir) {
152
187
  this.push(file);
153
188
  return cb();
154
189
  }
155
190
 
156
- if (!json.usingComponents || typeof json.usingComponents !== 'object') {
157
- this.push(file);
158
- return cb();
159
- }
160
-
161
- // 计算当前文件的编译输出路径
162
- const currentFileSrcPath = file.history[0] || file.path;
163
- const relativeToModuleSrc = path.relative(moduleFromPath, currentFileSrcPath);
164
- const currentFileDestPath = path.join(moduleDestPath, relativeToModuleSrc);
165
-
166
- // 延迟获取有效模块路径集合(首次文件处理时计算并缓存)
167
191
  const validModulePaths = getValidModulePaths(tmsConfig);
168
-
169
- const keysToRemove = [];
170
- Object.keys(json.usingComponents).forEach((componentKey) => {
171
- const componentPath = json.usingComponents[componentKey];
172
- if (shouldRemoveComponent(componentPath, currentFileDestPath, outputDir, moduleDestPath, validModulePaths)) {
173
- keysToRemove.push(componentKey);
174
- }
175
- });
176
-
177
- if (keysToRemove.length > 0) {
178
- keysToRemove.forEach((key) => {
179
- info(`[strictModulesFilter] 移除 ${path.basename(currentFileSrcPath)} 中的组件引用: ${key} -> ${json.usingComponents[key]}`);
180
- delete json.usingComponents[key];
181
- // 同步清理 componentPlaceholder
182
- if (json.componentPlaceholder && json.componentPlaceholder[key]) {
183
- delete json.componentPlaceholder[key];
184
- }
185
- });
186
-
187
- file.contents = Buffer.from(JSON.stringify(json, null, 2));
188
- }
189
-
190
- this.push(file);
191
- cb();
192
+ this.push(processJsonFile(file, moduleDestPath, moduleFromPath, outputDir, validModulePaths));
193
+ return cb();
192
194
  });
193
195
  }
194
196
 
@@ -168,6 +168,58 @@ function mergeSubPackages(existingPackages, newPackages) {
168
168
  return resultPackages;
169
169
  }
170
170
 
171
+ /**
172
+ * 清理 preloadRule 中引用了不存在分包的条目
173
+ */
174
+ function cleanPreloadRule(appJson) {
175
+ if (!appJson.preloadRule) return;
176
+
177
+ const subpackages = appJson.subpackages || [];
178
+ const existingSubpackageNames = new Set(subpackages.map(sub => sub.name).filter(Boolean));
179
+ const existingSubpackageRoots = new Set(subpackages.map(sub => sub.root).filter(Boolean));
180
+
181
+ Object.keys(appJson.preloadRule).forEach((pageKey) => {
182
+ const rule = appJson.preloadRule[pageKey];
183
+ if (rule.packages) {
184
+ rule.packages = rule.packages.filter(pkg => existingSubpackageNames.has(pkg) || existingSubpackageRoots.has(pkg));
185
+ if (rule.packages.length === 0) {
186
+ delete appJson.preloadRule[pageKey];
187
+ }
188
+ }
189
+ });
190
+
191
+ if (Object.keys(appJson.preloadRule).length === 0) {
192
+ delete appJson.preloadRule;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * 清理 entranceDeclare 中引用了不存在页面的条目
198
+ */
199
+ function cleanEntranceDeclare(appJson) {
200
+ // 收集所有有效页面路径(主包 pages + 分包 pages)
201
+ const allValidPages = new Set(appJson.pages || []);
202
+ (appJson.subpackages || []).forEach((sub) => {
203
+ (sub.pages || []).forEach((page) => {
204
+ allValidPages.add(`${sub.root}/${page}`);
205
+ });
206
+ });
207
+
208
+ if (!appJson.entranceDeclare) return;
209
+
210
+ Object.keys(appJson.entranceDeclare).forEach((key) => {
211
+ const entry = appJson.entranceDeclare[key];
212
+ if (entry && entry.path && !allValidPages.has(entry.path)) {
213
+ info(`[devStrictModulesInclude] 移除 entranceDeclare.${key},页面 ${entry.path} 不存在`);
214
+ delete appJson.entranceDeclare[key];
215
+ }
216
+ });
217
+
218
+ if (Object.keys(appJson.entranceDeclare).length === 0) {
219
+ delete appJson.entranceDeclare;
220
+ }
221
+ }
222
+
171
223
  /**
172
224
  * 动态生成编译后的app.json
173
225
  * @param {object} tmsConfig
@@ -193,53 +245,10 @@ async function buildOutputAppJson(tmsConfig, modules) {
193
245
  // 更新主包,需在subpackages处理完成后执行, pages/
194
246
  updateMainPackages(appJson, tmsConfig.mainPackages);
195
247
 
196
- // devStrictModulesInclude 模式下,清理 preloadRule 中引用了不存在分包的条目
197
- if (tmsConfig.devStrictModulesInclude && appJson.preloadRule) {
198
- const existingSubpackageNames = new Set(
199
- (appJson.subpackages || []).map(sub => sub.name).filter(Boolean),
200
- );
201
- const existingSubpackageRoots = new Set(
202
- (appJson.subpackages || []).map(sub => sub.root).filter(Boolean),
203
- );
204
- Object.keys(appJson.preloadRule).forEach((pageKey) => {
205
- const rule = appJson.preloadRule[pageKey];
206
- if (rule.packages) {
207
- rule.packages = rule.packages.filter(
208
- pkg => existingSubpackageNames.has(pkg) || existingSubpackageRoots.has(pkg),
209
- );
210
- if (rule.packages.length === 0) {
211
- delete appJson.preloadRule[pageKey];
212
- }
213
- }
214
- });
215
- if (Object.keys(appJson.preloadRule).length === 0) {
216
- delete appJson.preloadRule;
217
- }
218
- }
219
-
220
- // devStrictModulesInclude 模式下,清理引用了不存在页面路径的字段
248
+ // devStrictModulesInclude 模式下,清理无效引用
221
249
  if (tmsConfig.devStrictModulesInclude) {
222
- // 收集所有有效页面路径(主包 pages + 分包 pages)
223
- const allValidPages = new Set(appJson.pages || []);
224
- (appJson.subpackages || []).forEach((sub) => {
225
- (sub.pages || []).forEach((page) => {
226
- allValidPages.add(`${sub.root}/${page}`);
227
- });
228
- });
229
-
230
- // 清理 entranceDeclare 中引用了不存在页面的条目
231
- if (appJson.entranceDeclare) {
232
- Object.keys(appJson.entranceDeclare).forEach((key) => {
233
- const entry = appJson.entranceDeclare[key];
234
- if (entry && entry.path && !allValidPages.has(entry.path)) {
235
- info(`[devStrictModulesInclude] 移除 entranceDeclare.${key},页面 ${entry.path} 不存在`);
236
- delete appJson.entranceDeclare[key];
237
- }
238
- });
239
- if (Object.keys(appJson.entranceDeclare).length === 0) {
240
- delete appJson.entranceDeclare;
241
- }
242
- }
250
+ cleanPreloadRule(appJson);
251
+ cleanEntranceDeclare(appJson);
243
252
  }
244
253
 
245
254
  // 模板渲染:先将 app.json 转为字符串,然后通过 preprocess 渲染