@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 +120 -109
- package/package.json +2 -2
- package/src/compile/plugins/strictModulesFilter.js +73 -71
- package/src/core/buildAppJson.js +55 -46
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
|
|
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
|
-
|
|
1598
|
-
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
2834
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
package/src/core/buildAppJson.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
223
|
-
|
|
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 渲染
|