@moluoxixi/create-app 2.0.408 → 2.0.410
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/test.js +168 -87
- package/dist/types/features.d.ts +7 -9
- package/dist/types/features.js +6 -25
- package/dist/types/index.d.ts +20 -13
- package/dist/utils/featureMapping.d.ts +5 -26
- package/dist/utils/featureMapping.js +24 -68
- package/dist/utils/generateFrameworkProject.d.ts +2 -0
- package/dist/utils/generateFrameworkProject.js +136 -21
- package/dist/utils/prompts.js +37 -7
- package/dist/utils/renderFeatures.d.ts +38 -1
- package/dist/utils/renderFeatures.js +121 -37
- package/dist/utils/routeModeMapping.d.ts +14 -0
- package/dist/utils/routeModeMapping.js +15 -0
- package/package.json +2 -3
- package/templates/common/base/package.json +1 -1
- package/templates/common/base/vite.config.ts.ejs +1 -1
- package/templates/react/base/package.json +1 -3
- package/templates/react/base/src/main.tsx.ejs +16 -43
- package/templates/react/features/pageRoutes/package.json +1 -0
- package/templates/react/micro-frontends/qiankun/base/package.json +6 -0
- package/templates/react/micro-frontends/qiankun/base/src/main.tsx.ejs +83 -0
- package/templates/react/micro-frontends/qiankun/base/vite.config.ts.ejs +93 -0
- package/templates/vue/base/package.json +1 -5
- package/templates/vue/base/src/main.ts.ejs +18 -41
- package/templates/vue/features/element-plus/src/layouts/element.vue +1 -4
- package/templates/vue/features/manualRoutes/package.json +0 -1
- package/templates/vue/features/manualRoutes/src/router/index.ts +11 -12
- package/templates/vue/features/manualRoutes/src/router/routes.ts +14 -23
- package/templates/vue/features/pageRoutes/package.json +0 -1
- package/templates/vue/features/pageRoutes/src/router/index.ts +11 -12
- package/templates/vue/features/pinia/node_modules/.bin/tsc +17 -0
- package/templates/vue/features/pinia/node_modules/.bin/tsc.CMD +12 -0
- package/templates/vue/features/pinia/node_modules/.bin/tsc.ps1 +41 -0
- package/templates/vue/features/pinia/node_modules/.bin/tsserver +17 -0
- package/templates/vue/features/pinia/node_modules/.bin/tsserver.CMD +12 -0
- package/templates/vue/features/pinia/node_modules/.bin/tsserver.ps1 +41 -0
- package/templates/vue/features/pinia/package.json +6 -0
- package/templates/vue/micro-frontends/qiankun/base/package.json +6 -0
- package/templates/vue/micro-frontends/qiankun/base/src/main.ts.ejs +87 -0
- package/templates/vue/micro-frontends/qiankun/base/vite.config.ts.ejs +93 -0
- package/templates/vue/micro-frontends/qiankun/features/element-plus/src/layouts/element.vue +120 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/jiti +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/jiti.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/jiti.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/sass +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/sass.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/sass.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/terser +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/terser.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/terser.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsc +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsc.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsc.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsserver +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsserver.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsserver.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsx +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsx.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsx.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/vite +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/vite.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/vite.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/yaml +17 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/yaml.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/yaml.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/package.json +5 -0
- package/templates/vue/micro-frontends/qiankun/features/manualRoutes/src/router/index.ts +56 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/jiti +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/jiti.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/jiti.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/sass +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/sass.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/sass.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/terser +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/terser.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/terser.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsc +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsc.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsc.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsserver +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsserver.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsserver.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsx +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsx.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsx.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/vite +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/vite.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/vite.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/yaml +17 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/yaml.CMD +12 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/yaml.ps1 +41 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/package.json +5 -0
- package/templates/vue/micro-frontends/qiankun/features/pageRoutes/src/router/index.ts +57 -0
- package/templates/react/base/src/qiankun/index.ts +0 -83
- package/templates/react/base/src/stores/user.ts +0 -55
- package/templates/vue/base/src/router/layout.vue +0 -15
- package/templates/vue/features/manualRoutes/src/stores/index.ts +0 -6
- package/templates/vue/features/manualRoutes/src/stores/modules/system.ts +0 -51
- package/templates/vue/features/manualRoutes/src/stores/modules/user.ts +0 -41
- package/templates/vue/features/pageRoutes/src/stores/index.ts +0 -6
- package/templates/vue/features/pageRoutes/src/stores/modules/system.ts +0 -51
- package/templates/vue/features/pageRoutes/src/stores/modules/user.ts +0 -41
- /package/templates/react/features/{router → manualRoutes}/package.json +0 -0
- /package/templates/react/{base → features/zustand}/src/stores/index.ts +0 -0
- /package/templates/vue/{base → features/pinia}/src/stores/index.ts +0 -0
- /package/templates/vue/{base → features/pinia}/src/stores/modules/system.ts +0 -0
- /package/templates/vue/{base → features/pinia}/src/stores/modules/user.ts +0 -0
package/dist/test.js
CHANGED
|
@@ -14,18 +14,58 @@ import fs from 'fs-extra';
|
|
|
14
14
|
import { FILE_CONSTANTS } from "./constants/index.js";
|
|
15
15
|
import { generateProject } from "./generators/index.js";
|
|
16
16
|
import { featureToConfig, scanAllFeatures } from "./utils/featureMapping.js";
|
|
17
|
+
import { getRouteModeFeatures } from "./utils/routeModeMapping.js";
|
|
17
18
|
const __filename = fileURLToPath(import.meta.url);
|
|
18
19
|
const __dirname = path.dirname(__filename);
|
|
19
20
|
/** 测试输出目录 */
|
|
20
21
|
const TEST_OUTPUT_DIR = path.resolve(__dirname, '../test');
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
+
* 测试配置
|
|
24
|
+
* 集中管理测试选项,方便随时调整
|
|
23
25
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const TEST_CONFIG = {
|
|
27
|
+
/** 固定默认值(不参与组合测试) */
|
|
28
|
+
defaults: {
|
|
29
|
+
/** 项目名称(会自动生成,此处为描述) */
|
|
30
|
+
projectName: 'auto-generated',
|
|
31
|
+
/** 项目描述 */
|
|
32
|
+
description: 'A Vite project',
|
|
33
|
+
/** 作者 */
|
|
34
|
+
author: 'test',
|
|
35
|
+
/** 是否启用国际化 */
|
|
36
|
+
i18n: true,
|
|
37
|
+
/** 是否启用错误监控 */
|
|
38
|
+
sentry: false,
|
|
39
|
+
/** 是否启用 ESLint */
|
|
40
|
+
eslint: true,
|
|
41
|
+
/** 是否启用 Git Hooks */
|
|
42
|
+
husky: true,
|
|
43
|
+
},
|
|
44
|
+
/** 参与组合测试的选项 */
|
|
45
|
+
combinations: {
|
|
46
|
+
/** 框架列表(空数组表示不启用) */
|
|
47
|
+
frameworks: ['vue', 'react'],
|
|
48
|
+
/** UI 库配置(按框架分组,空数组表示不启用,需要明确配置才启用) */
|
|
49
|
+
uiLibraries: {
|
|
50
|
+
vue: ['element-plus', 'ant-design-vue'], // Vue 可用的 UI 库
|
|
51
|
+
react: ['ant-design'], // React 可用的 UI 库
|
|
52
|
+
},
|
|
53
|
+
/** 路由模式列表(空数组表示不启用) */
|
|
54
|
+
routeModes: ['manualRoutes', 'pageRoutes'],
|
|
55
|
+
/** 微前端引擎列表(空数组表示不启用) */
|
|
56
|
+
microFrontendEngines: ['qiankun'],
|
|
57
|
+
/** 包管理器列表(空数组表示不启用) */
|
|
58
|
+
packageManagers: ['pnpm'],
|
|
59
|
+
/** 是否测试 i18n 的组合 */
|
|
60
|
+
i18n: false,
|
|
61
|
+
/** 是否测试 sentry 的组合 */
|
|
62
|
+
sentry: false,
|
|
63
|
+
/** 是否测试 eslint 的组合 */
|
|
64
|
+
eslint: false,
|
|
65
|
+
/** 是否测试 husky 的组合 */
|
|
66
|
+
husky: false,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
29
69
|
/**
|
|
30
70
|
* 生成所有可能的组合(包括全开、全关)
|
|
31
71
|
*/
|
|
@@ -44,11 +84,16 @@ function generateAllCombinations(items) {
|
|
|
44
84
|
}
|
|
45
85
|
/**
|
|
46
86
|
* 自动生成测试用例配置(基于组合算法)
|
|
47
|
-
* @param minimalOnly 是否只生成全量和最小配置
|
|
48
87
|
*/
|
|
49
|
-
function generateTestConfigs(
|
|
88
|
+
function generateTestConfigs() {
|
|
50
89
|
const configs = [];
|
|
51
|
-
|
|
90
|
+
// 框架列表(空数组表示不启用)
|
|
91
|
+
const frameworks = TEST_CONFIG.combinations.frameworks.length > 0
|
|
92
|
+
? TEST_CONFIG.combinations.frameworks
|
|
93
|
+
: [];
|
|
94
|
+
if (frameworks.length === 0) {
|
|
95
|
+
return configs;
|
|
96
|
+
}
|
|
52
97
|
for (const framework of frameworks) {
|
|
53
98
|
const allFeatures = scanAllFeatures(framework);
|
|
54
99
|
// 分离不同类型的 features
|
|
@@ -71,74 +116,104 @@ function generateTestConfigs(minimalOnly = false) {
|
|
|
71
116
|
}
|
|
72
117
|
if (uiLibraries.length === 0)
|
|
73
118
|
continue;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
//
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
routeMode: featureToConfig(routeModeFeature, framework).value,
|
|
90
|
-
packageManager,
|
|
91
|
-
};
|
|
92
|
-
// 应用布尔 features 的组合
|
|
93
|
-
for (let i = 0; i < booleanFeatures.length; i++) {
|
|
94
|
-
const feature = booleanFeatures[i];
|
|
95
|
-
const enabled = combination[i];
|
|
96
|
-
const featureConfig = featureToConfig(feature, framework);
|
|
97
|
-
if (featureConfig && featureConfig.key !== 'uiLibrary' && featureConfig.key !== 'routeMode') {
|
|
98
|
-
config[featureConfig.key] = enabled;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// 生成测试用例名称(包含包管理器)
|
|
102
|
-
const suffix = combination.every(v => !v) ? 'minimal' : 'full';
|
|
103
|
-
configs.push(createTestConfig(framework, uiLibrary, `${packageManager}-${suffix}`, config));
|
|
119
|
+
// 过滤掉不需要测试的布尔特性(根据 combinations 配置决定)
|
|
120
|
+
// 过滤掉根据框架自动选择的特性(pinia/zustand)
|
|
121
|
+
const autoSelectedFeatures = framework === 'vue' ? ['pinia'] : ['zustand'];
|
|
122
|
+
const filteredBooleanFeatures = booleanFeatures.filter((feature) => {
|
|
123
|
+
// 排除自动选择的特性
|
|
124
|
+
if (autoSelectedFeatures.includes(feature)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
// 根据 combinations 配置决定是否参与组合测试
|
|
128
|
+
const featureConfig = featureToConfig(feature, framework);
|
|
129
|
+
if (featureConfig && featureConfig.key in TEST_CONFIG.combinations) {
|
|
130
|
+
const combinationValue = TEST_CONFIG.combinations[featureConfig.key];
|
|
131
|
+
// 如果是数组(frameworks, uiLibraries, routeModes, packageManagers),跳过
|
|
132
|
+
if (Array.isArray(combinationValue)) {
|
|
133
|
+
return true;
|
|
104
134
|
}
|
|
135
|
+
// 其他布尔特性根据配置决定(i18n, sentry, eslint, husky)
|
|
136
|
+
// 使用 Boolean() 转换,避免类型检查问题
|
|
137
|
+
return Boolean(combinationValue);
|
|
105
138
|
}
|
|
139
|
+
// 默认参与组合测试
|
|
140
|
+
return true;
|
|
141
|
+
});
|
|
142
|
+
// 生成所有组合
|
|
143
|
+
// UI 库列表(按框架分组配置,空数组表示不启用)
|
|
144
|
+
const frameworkUiLibraries = TEST_CONFIG.combinations.uiLibraries[framework] || [];
|
|
145
|
+
// 如果配置为空数组,表示不启用该框架的 UI 库测试
|
|
146
|
+
if (frameworkUiLibraries.length === 0) {
|
|
147
|
+
continue;
|
|
106
148
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
149
|
+
// 只测试配置中指定的 UI 库
|
|
150
|
+
const uiLibrariesToTest = uiLibraries.filter(uiLib => frameworkUiLibraries.includes(uiLib));
|
|
151
|
+
if (uiLibrariesToTest.length === 0) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
for (const uiLibrary of uiLibrariesToTest) {
|
|
155
|
+
// 路由模式列表(空数组表示不启用,使用默认值)
|
|
156
|
+
const routeModesToTest = TEST_CONFIG.combinations.routeModes.length > 0
|
|
157
|
+
? routeModes.filter(routeMode => TEST_CONFIG.combinations.routeModes.includes(routeMode))
|
|
158
|
+
: (routeModes.length > 0 ? routeModes : ['manualRoutes']); // 默认
|
|
159
|
+
if (routeModesToTest.length === 0) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
for (const routeModeFeature of routeModesToTest) {
|
|
163
|
+
// 微前端引擎列表(空数组表示不启用)
|
|
164
|
+
const microFrontendEnginesToTest = TEST_CONFIG.combinations.microFrontendEngines;
|
|
165
|
+
// 如果配置了微前端引擎,生成两种组合:不带微前端(null)和带微前端(配置的引擎)
|
|
166
|
+
// 如果没配置,只生成不带微前端的组合
|
|
167
|
+
const microFrontendOptions = microFrontendEnginesToTest.length > 0
|
|
168
|
+
? [null, ...microFrontendEnginesToTest] // 总是包含 null(不带),再加上配置的引擎
|
|
169
|
+
: [null]; // 如果没配置,只生成不带微前端的
|
|
170
|
+
for (const microFrontendEngine of microFrontendOptions) {
|
|
113
171
|
// 生成所有布尔 features 的组合(2^n 种)
|
|
114
|
-
const combinations = generateAllCombinations(
|
|
115
|
-
//
|
|
116
|
-
const
|
|
117
|
-
|
|
172
|
+
const combinations = generateAllCombinations(filteredBooleanFeatures);
|
|
173
|
+
// 包管理器列表(空数组表示不启用)
|
|
174
|
+
const packageManagersToTest = TEST_CONFIG.combinations.packageManagers;
|
|
175
|
+
if (packageManagersToTest.length === 0) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
for (const packageManager of packageManagersToTest) {
|
|
118
179
|
for (const combination of combinations) {
|
|
119
180
|
const config = {
|
|
120
181
|
framework,
|
|
121
182
|
uiLibrary: uiLibrary,
|
|
122
183
|
routeMode: featureToConfig(routeModeFeature, framework).value,
|
|
123
184
|
packageManager,
|
|
185
|
+
microFrontend: microFrontendEngine !== null,
|
|
186
|
+
microFrontendEngine: microFrontendEngine || undefined,
|
|
124
187
|
};
|
|
188
|
+
// 根据 routeMode 设置对应的布尔 feature
|
|
189
|
+
const routeModeFeatures = getRouteModeFeatures(routeModeFeature);
|
|
190
|
+
config.manualRoutes = routeModeFeatures.manualRoutes;
|
|
191
|
+
config.pageRoutes = routeModeFeatures.pageRoutes;
|
|
125
192
|
// 应用布尔 features 的组合
|
|
126
|
-
for (let i = 0; i <
|
|
127
|
-
const feature =
|
|
193
|
+
for (let i = 0; i < filteredBooleanFeatures.length; i++) {
|
|
194
|
+
const feature = filteredBooleanFeatures[i];
|
|
128
195
|
const enabled = combination[i];
|
|
129
196
|
const featureConfig = featureToConfig(feature, framework);
|
|
130
197
|
if (featureConfig && featureConfig.key !== 'uiLibrary' && featureConfig.key !== 'routeMode') {
|
|
131
198
|
config[featureConfig.key] = enabled;
|
|
132
199
|
}
|
|
133
200
|
}
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
const suffix =
|
|
137
|
-
? '
|
|
138
|
-
:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
201
|
+
// 生成测试用例名称
|
|
202
|
+
// 如果没有布尔特性组合,使用固定后缀
|
|
203
|
+
const suffix = filteredBooleanFeatures.length === 0
|
|
204
|
+
? 'default'
|
|
205
|
+
: (() => {
|
|
206
|
+
const enabledFeatures = filteredBooleanFeatures.filter((_, i) => combination[i]);
|
|
207
|
+
return enabledFeatures.length === 0
|
|
208
|
+
? 'minimal'
|
|
209
|
+
: enabledFeatures.length === filteredBooleanFeatures.length
|
|
210
|
+
? 'full'
|
|
211
|
+
: enabledFeatures.join('-');
|
|
212
|
+
})();
|
|
213
|
+
// 生成测试用例名称
|
|
214
|
+
const packageManagerSuffix = TEST_CONFIG.combinations.packageManagers.length > 1 ? `${packageManager}-` : '';
|
|
215
|
+
const microFrontendSuffix = microFrontendEngine ? `${microFrontendEngine}-` : '';
|
|
216
|
+
configs.push(createTestConfig(framework, uiLibrary, `${packageManagerSuffix}${microFrontendSuffix}${routeModeFeature}-${suffix}`, config));
|
|
142
217
|
}
|
|
143
218
|
}
|
|
144
219
|
}
|
|
@@ -160,23 +235,28 @@ function createTestConfig(framework, uiLibrary, suffix, overrides) {
|
|
|
160
235
|
return {
|
|
161
236
|
name,
|
|
162
237
|
config: {
|
|
238
|
+
// 固定默认值,不参与组合测试
|
|
163
239
|
projectName: name,
|
|
164
|
-
description:
|
|
165
|
-
author:
|
|
240
|
+
description: TEST_CONFIG.defaults.description,
|
|
241
|
+
author: TEST_CONFIG.defaults.author,
|
|
242
|
+
// 固定默认值,不参与组合测试(避免几何级增长)
|
|
243
|
+
i18n: TEST_CONFIG.defaults.i18n,
|
|
244
|
+
sentry: TEST_CONFIG.defaults.sentry,
|
|
245
|
+
eslint: TEST_CONFIG.defaults.eslint,
|
|
246
|
+
husky: TEST_CONFIG.defaults.husky,
|
|
247
|
+
packageManager: TEST_CONFIG.combinations.packageManagers[0],
|
|
166
248
|
...overrides,
|
|
167
249
|
},
|
|
168
250
|
};
|
|
169
251
|
}
|
|
170
252
|
/**
|
|
171
253
|
* 生成测试项目
|
|
172
|
-
* @param minimalOnly 是否只生成全量和最小配置
|
|
173
254
|
* @returns Promise<void>
|
|
174
255
|
*/
|
|
175
|
-
async function generateTestProjects(
|
|
176
|
-
|
|
177
|
-
console.log(chalk.blue.bold(`\n🧪 开始生成测试项目${mode}...\n`));
|
|
256
|
+
async function generateTestProjects() {
|
|
257
|
+
console.log(chalk.blue.bold('\n🧪 开始生成测试项目...\n'));
|
|
178
258
|
// 扫描并生成测试配置
|
|
179
|
-
const TEST_CONFIGS = generateTestConfigs(
|
|
259
|
+
const TEST_CONFIGS = generateTestConfigs();
|
|
180
260
|
console.log(chalk.cyan(`📋 扫描到 ${TEST_CONFIGS.length} 个测试用例\n`));
|
|
181
261
|
// 清理并创建测试目录
|
|
182
262
|
if (fs.existsSync(TEST_OUTPUT_DIR)) {
|
|
@@ -193,20 +273,26 @@ async function generateTestProjects(minimalOnly = false) {
|
|
|
193
273
|
// 根据框架决定输出目录
|
|
194
274
|
const frameworkOutputDir = config.framework === 'vue' ? vueOutputDir : reactOutputDir;
|
|
195
275
|
const fullConfig = {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
276
|
+
// 固定默认值(不参与组合测试)
|
|
277
|
+
projectName: config.projectName || name,
|
|
278
|
+
description: config.description || TEST_CONFIG.defaults.description,
|
|
279
|
+
author: config.author || TEST_CONFIG.defaults.author,
|
|
199
280
|
framework: config.framework,
|
|
200
281
|
uiLibrary: config.uiLibrary,
|
|
201
282
|
routeMode: config.routeMode,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
283
|
+
// feature 名称与目录名称一致
|
|
284
|
+
pinia: config.framework === 'vue',
|
|
285
|
+
zustand: config.framework === 'react',
|
|
286
|
+
...getRouteModeFeatures(config.routeMode),
|
|
287
|
+
// 固定默认值(不参与组合测试,避免几何级增长)
|
|
288
|
+
i18n: config.i18n ?? TEST_CONFIG.defaults.i18n,
|
|
289
|
+
sentry: config.sentry ?? TEST_CONFIG.defaults.sentry,
|
|
290
|
+
eslint: config.eslint ?? TEST_CONFIG.defaults.eslint,
|
|
291
|
+
husky: config.husky ?? TEST_CONFIG.defaults.husky,
|
|
292
|
+
// 参与组合测试的特性
|
|
293
|
+
microFrontend: config.microFrontend ?? false,
|
|
294
|
+
microFrontendEngine: config.microFrontendEngine,
|
|
295
|
+
packageManager: config.packageManager ?? TEST_CONFIG.combinations.packageManagers[0],
|
|
210
296
|
targetDir: path.join(frameworkOutputDir, name),
|
|
211
297
|
};
|
|
212
298
|
try {
|
|
@@ -257,11 +343,10 @@ function checkPackageJsonVersions(projectDir) {
|
|
|
257
343
|
}
|
|
258
344
|
/**
|
|
259
345
|
* 审计 @moluoxixi 依赖
|
|
260
|
-
* @param minimalOnly 是否只生成全量和最小配置
|
|
261
346
|
*/
|
|
262
|
-
async function auditMoluoxixiDeps(
|
|
347
|
+
async function auditMoluoxixiDeps() {
|
|
263
348
|
console.log(chalk.blue.bold('\n🔍 开始审计 @moluoxixi 依赖...\n'));
|
|
264
|
-
const TEST_CONFIGS = generateTestConfigs(
|
|
349
|
+
const TEST_CONFIGS = generateTestConfigs();
|
|
265
350
|
const requiredDeps = [
|
|
266
351
|
'@moluoxixi/vite-config',
|
|
267
352
|
'@moluoxixi/ajax-package',
|
|
@@ -312,7 +397,7 @@ async function auditMoluoxixiDeps(minimalOnly = false) {
|
|
|
312
397
|
console.log(chalk.green(` ✅ eslint.config.ts 已正确移除`));
|
|
313
398
|
}
|
|
314
399
|
}
|
|
315
|
-
if (!config.
|
|
400
|
+
if (!config.husky) {
|
|
316
401
|
const huskyDir = path.join(projectDir, '.husky');
|
|
317
402
|
if (fs.existsSync(huskyDir)) {
|
|
318
403
|
console.log(chalk.red(` ❌ 不应存在 .husky/ 目录(Git Hooks 已禁用)`));
|
|
@@ -400,17 +485,13 @@ async function printFileTree(dir, indent) {
|
|
|
400
485
|
* @returns Promise<void>
|
|
401
486
|
*/
|
|
402
487
|
async function main() {
|
|
403
|
-
const { minimalOnly } = parseArgs();
|
|
404
488
|
console.log(chalk.blue.bold(`\n${'='.repeat(60)}`));
|
|
405
489
|
console.log(chalk.blue.bold(' Vite CLI Next - 产物审计测试'));
|
|
406
|
-
if (minimalOnly) {
|
|
407
|
-
console.log(chalk.yellow.bold(' 模式: 仅全量和最小配置'));
|
|
408
|
-
}
|
|
409
490
|
console.log(chalk.blue.bold('='.repeat(60)));
|
|
410
491
|
// 1. 生成测试项目
|
|
411
|
-
await generateTestProjects(
|
|
492
|
+
await generateTestProjects();
|
|
412
493
|
// 2. 审计 @moluoxixi 依赖
|
|
413
|
-
await auditMoluoxixiDeps(
|
|
494
|
+
await auditMoluoxixiDeps();
|
|
414
495
|
// 3. 显示文件树
|
|
415
496
|
await showFileTrees();
|
|
416
497
|
console.log(chalk.green.bold('\n✅ 全量产物审计完成!\n'));
|
package/dist/types/features.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 特性配置定义
|
|
3
|
-
*
|
|
3
|
+
* 核心依赖和微前端引擎类型定义
|
|
4
|
+
*
|
|
5
|
+
* 注意:Features 现在通过文件系统扫描自动发现,无需在此维护常量列表
|
|
6
|
+
* 参考:src/utils/renderFeatures.ts
|
|
4
7
|
*/
|
|
5
8
|
/**
|
|
6
9
|
* @moluoxixi 核心依赖配置
|
|
@@ -14,12 +17,7 @@ export declare const MOLUOXIXI_DEPS: {
|
|
|
14
17
|
readonly '@moluoxixi/css-module-global-root-plugin': "latest";
|
|
15
18
|
};
|
|
16
19
|
/**
|
|
17
|
-
*
|
|
20
|
+
* 微前端引擎类型
|
|
18
21
|
*/
|
|
19
|
-
export declare const
|
|
20
|
-
|
|
21
|
-
* React 特性 ID
|
|
22
|
-
*/
|
|
23
|
-
export declare const REACT_FEATURES: readonly ["router", "zustand", "eslint", "i18n", "sentry", "qiankun", "ant-design"];
|
|
24
|
-
export type VueFeatureId = typeof VUE_FEATURES[number];
|
|
25
|
-
export type ReactFeatureId = typeof REACT_FEATURES[number];
|
|
22
|
+
export declare const MICRO_FRONTEND_ENGINES: readonly ["qiankun", "micro-app"];
|
|
23
|
+
export type MicroFrontendEngine = typeof MICRO_FRONTEND_ENGINES[number];
|
package/dist/types/features.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 特性配置定义
|
|
3
|
-
*
|
|
3
|
+
* 核心依赖和微前端引擎类型定义
|
|
4
|
+
*
|
|
5
|
+
* 注意:Features 现在通过文件系统扫描自动发现,无需在此维护常量列表
|
|
6
|
+
* 参考:src/utils/renderFeatures.ts
|
|
4
7
|
*/
|
|
5
8
|
/**
|
|
6
9
|
* @moluoxixi 核心依赖配置
|
|
@@ -14,28 +17,6 @@ export const MOLUOXIXI_DEPS = {
|
|
|
14
17
|
'@moluoxixi/css-module-global-root-plugin': 'latest',
|
|
15
18
|
};
|
|
16
19
|
/**
|
|
17
|
-
*
|
|
20
|
+
* 微前端引擎类型
|
|
18
21
|
*/
|
|
19
|
-
export const
|
|
20
|
-
'router',
|
|
21
|
-
'pinia',
|
|
22
|
-
'eslint',
|
|
23
|
-
'i18n',
|
|
24
|
-
'sentry',
|
|
25
|
-
'qiankun',
|
|
26
|
-
'pageRoutes',
|
|
27
|
-
'element-plus',
|
|
28
|
-
'ant-design-vue',
|
|
29
|
-
];
|
|
30
|
-
/**
|
|
31
|
-
* React 特性 ID
|
|
32
|
-
*/
|
|
33
|
-
export const REACT_FEATURES = [
|
|
34
|
-
'router',
|
|
35
|
-
'zustand',
|
|
36
|
-
'eslint',
|
|
37
|
-
'i18n',
|
|
38
|
-
'sentry',
|
|
39
|
-
'qiankun',
|
|
40
|
-
'ant-design',
|
|
41
|
-
];
|
|
22
|
+
export const MICRO_FRONTEND_ENGINES = ['qiankun', 'micro-app'];
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* CLI 类型定义
|
|
3
3
|
* 定义项目配置、模板层级等核心类型
|
|
4
4
|
*/
|
|
5
|
+
import type { MicroFrontendEngine } from './features.ts';
|
|
5
6
|
export * from './ejs.ts';
|
|
6
7
|
export * from './features.ts';
|
|
7
8
|
/**
|
|
@@ -15,7 +16,7 @@ export type UILibraryType = 'element-plus' | 'ant-design-vue' | 'ant-design';
|
|
|
15
16
|
/**
|
|
16
17
|
* 路由模式类型
|
|
17
18
|
*/
|
|
18
|
-
export type RouteModeType = '
|
|
19
|
+
export type RouteModeType = 'manualRoutes' | 'pageRoutes';
|
|
19
20
|
/**
|
|
20
21
|
* 包管理器类型
|
|
21
22
|
*/
|
|
@@ -32,24 +33,30 @@ export interface ProjectConfigType {
|
|
|
32
33
|
author: string;
|
|
33
34
|
/** 框架类型 */
|
|
34
35
|
framework: FrameworkType;
|
|
35
|
-
/** UI
|
|
36
|
+
/** UI 库(feature 名称:element-plus | ant-design-vue | ant-design) */
|
|
36
37
|
uiLibrary: UILibraryType;
|
|
37
|
-
/**
|
|
38
|
+
/** 路由模式(决定使用 manualRoutes 还是 pageRoutes feature) */
|
|
38
39
|
routeMode: RouteModeType;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
/**
|
|
40
|
+
/** 是否启用 pinia/zustand feature */
|
|
41
|
+
pinia?: boolean;
|
|
42
|
+
/** 是否启用 zustand feature (React) */
|
|
43
|
+
zustand?: boolean;
|
|
44
|
+
/** 是否启用 manualRoutes feature */
|
|
45
|
+
manualRoutes?: boolean;
|
|
46
|
+
/** 是否启用 pageRoutes feature */
|
|
47
|
+
pageRoutes?: boolean;
|
|
48
|
+
/** 是否启用 i18n feature */
|
|
44
49
|
i18n: boolean;
|
|
45
50
|
/** 是否启用微前端支持 */
|
|
46
|
-
|
|
47
|
-
/**
|
|
51
|
+
microFrontend: boolean;
|
|
52
|
+
/** 微前端引擎(qiankun、micro-app 等)- 当 microFrontend 为 true 时有效 */
|
|
53
|
+
microFrontendEngine?: MicroFrontendEngine;
|
|
54
|
+
/** 是否启用 sentry feature */
|
|
48
55
|
sentry: boolean;
|
|
49
|
-
/** 是否启用
|
|
56
|
+
/** 是否启用 eslint feature */
|
|
50
57
|
eslint: boolean;
|
|
51
|
-
/** 是否启用
|
|
52
|
-
|
|
58
|
+
/** 是否启用 husky feature (Git Hooks) */
|
|
59
|
+
husky: boolean;
|
|
53
60
|
/** 包管理器 */
|
|
54
61
|
packageManager: PackageManagerType;
|
|
55
62
|
/** 目标目录 */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Features 映射工具
|
|
3
|
-
*
|
|
3
|
+
* 用于测试用例生成和 feature 扫描
|
|
4
|
+
* 注意:配置名称与 feature 目录名称完全一致,无需额外映射
|
|
4
5
|
*/
|
|
5
6
|
import type { FrameworkType } from '../types/index.ts';
|
|
6
7
|
/**
|
|
@@ -9,36 +10,14 @@ import type { FrameworkType } from '../types/index.ts';
|
|
|
9
10
|
* @returns 所有 feature 名称数组(UI 库按优先级排序)
|
|
10
11
|
*/
|
|
11
12
|
export declare function scanAllFeatures(framework: FrameworkType): string[];
|
|
12
|
-
/**
|
|
13
|
-
* 配置项到 feature 目录的映射(从 renderFeatures 提取)
|
|
14
|
-
* @param _framework 框架类型(已不再使用,保留以保持接口兼容性)
|
|
15
|
-
* @returns 配置键到 feature 名称的映射对象
|
|
16
|
-
*/
|
|
17
|
-
export declare function getConfigToFeatureMap(_framework: FrameworkType): Record<string, string>;
|
|
18
|
-
/**
|
|
19
|
-
* 公共 features 映射
|
|
20
|
-
* @returns 公共配置键到 feature 名称的映射对象
|
|
21
|
-
*/
|
|
22
|
-
export declare function getCommonFeatureMap(): Record<string, string>;
|
|
23
|
-
/**
|
|
24
|
-
* 路由模式映射
|
|
25
|
-
* @param routeMode 路由模式('manual' 或 'file-system')
|
|
26
|
-
* @returns feature 名称
|
|
27
|
-
*/
|
|
28
|
-
export declare function getRouteModeFeature(routeMode: string): string;
|
|
29
|
-
/**
|
|
30
|
-
* UI 库映射
|
|
31
|
-
* @param uiLibrary UI 库名称
|
|
32
|
-
* @returns feature 名称(通常与 UI 库名称相同)
|
|
33
|
-
*/
|
|
34
|
-
export declare function getUILibraryFeature(uiLibrary: string): string;
|
|
35
13
|
/**
|
|
36
14
|
* Feature 名称转换为配置键和值(用于测试用例生成)
|
|
15
|
+
* 注意:大部分情况下 feature 名称 === 配置名称
|
|
37
16
|
* @param feature feature 名称
|
|
38
|
-
* @param
|
|
17
|
+
* @param _framework 框架类型(保留参数以保持接口兼容性)
|
|
39
18
|
* @returns 配置键值对,如果无法映射则返回 null
|
|
40
19
|
*/
|
|
41
|
-
export declare function featureToConfig(feature: string,
|
|
20
|
+
export declare function featureToConfig(feature: string, _framework: FrameworkType): {
|
|
42
21
|
key: string;
|
|
43
22
|
value: string | boolean;
|
|
44
23
|
} | null;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Features 映射工具
|
|
3
|
-
*
|
|
3
|
+
* 用于测试用例生成和 feature 扫描
|
|
4
|
+
* 注意:配置名称与 feature 目录名称完全一致,无需额外映射
|
|
4
5
|
*/
|
|
5
6
|
import fs from 'fs-extra';
|
|
6
7
|
import path from 'node:path';
|
|
@@ -39,79 +40,34 @@ export function scanAllFeatures(framework) {
|
|
|
39
40
|
return a.localeCompare(b);
|
|
40
41
|
});
|
|
41
42
|
}
|
|
42
|
-
/**
|
|
43
|
-
* 配置项到 feature 目录的映射(从 renderFeatures 提取)
|
|
44
|
-
* @param _framework 框架类型(已不再使用,保留以保持接口兼容性)
|
|
45
|
-
* @returns 配置键到 feature 名称的映射对象
|
|
46
|
-
*/
|
|
47
|
-
export function getConfigToFeatureMap(_framework) {
|
|
48
|
-
return {
|
|
49
|
-
// router、stateManagement、qiankun 已内置到 base,不再作为 feature
|
|
50
|
-
eslint: 'eslint',
|
|
51
|
-
i18n: 'i18n',
|
|
52
|
-
sentry: 'sentry',
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* 公共 features 映射
|
|
57
|
-
* @returns 公共配置键到 feature 名称的映射对象
|
|
58
|
-
*/
|
|
59
|
-
export function getCommonFeatureMap() {
|
|
60
|
-
return {
|
|
61
|
-
gitHooks: 'husky',
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* 路由模式映射
|
|
66
|
-
* @param routeMode 路由模式('manual' 或 'file-system')
|
|
67
|
-
* @returns feature 名称
|
|
68
|
-
*/
|
|
69
|
-
export function getRouteModeFeature(routeMode) {
|
|
70
|
-
return routeMode === 'manual' ? 'manualRoutes' : 'pageRoutes';
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* UI 库映射
|
|
74
|
-
* @param uiLibrary UI 库名称
|
|
75
|
-
* @returns feature 名称(通常与 UI 库名称相同)
|
|
76
|
-
*/
|
|
77
|
-
export function getUILibraryFeature(uiLibrary) {
|
|
78
|
-
return uiLibrary;
|
|
79
|
-
}
|
|
80
43
|
/**
|
|
81
44
|
* Feature 名称转换为配置键和值(用于测试用例生成)
|
|
45
|
+
* 注意:大部分情况下 feature 名称 === 配置名称
|
|
82
46
|
* @param feature feature 名称
|
|
83
|
-
* @param
|
|
47
|
+
* @param _framework 框架类型(保留参数以保持接口兼容性)
|
|
84
48
|
* @returns 配置键值对,如果无法映射则返回 null
|
|
85
49
|
*/
|
|
86
|
-
export function featureToConfig(feature,
|
|
87
|
-
//
|
|
88
|
-
if (feature === 'manualRoutes')
|
|
89
|
-
return { key: 'routeMode', value: 'manual' };
|
|
90
|
-
if (feature === 'pageRoutes')
|
|
91
|
-
return { key: 'routeMode', value: 'file-system' };
|
|
92
|
-
// UI 库
|
|
50
|
+
export function featureToConfig(feature, _framework) {
|
|
51
|
+
// UI 库:配置键是 uiLibrary,值是 feature 名称
|
|
93
52
|
const uiLibraries = ['element-plus', 'ant-design-vue', 'ant-design'];
|
|
94
|
-
if (uiLibraries.includes(feature))
|
|
53
|
+
if (uiLibraries.includes(feature)) {
|
|
95
54
|
return { key: 'uiLibrary', value: feature };
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const commonKey = Object.keys(commonMap).find(key => commonMap[key] === feature);
|
|
114
|
-
if (commonKey)
|
|
115
|
-
return { key: commonKey, value: true };
|
|
55
|
+
}
|
|
56
|
+
// 路由模式 features:用于测试分类
|
|
57
|
+
if (feature === 'manualRoutes' || feature === 'pageRoutes') {
|
|
58
|
+
return { key: 'routeMode', value: feature };
|
|
59
|
+
}
|
|
60
|
+
// 布尔类型的 features:配置名 === feature 名
|
|
61
|
+
const booleanFeatures = [
|
|
62
|
+
'eslint',
|
|
63
|
+
'i18n',
|
|
64
|
+
'sentry',
|
|
65
|
+
'pinia',
|
|
66
|
+
'zustand',
|
|
67
|
+
'husky',
|
|
68
|
+
];
|
|
69
|
+
if (booleanFeatures.includes(feature)) {
|
|
70
|
+
return { key: feature, value: true };
|
|
71
|
+
}
|
|
116
72
|
return null;
|
|
117
73
|
}
|