@moluoxixi/create-app 2.0.407 → 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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 框架项目生成通用工具
|
|
3
3
|
* 抽离 react.ts 和 vue.ts 的公共逻辑
|
|
4
|
+
* 支持三层嵌套优先级(L1: common, L2: framework, L3: micro-frontend)
|
|
4
5
|
*/
|
|
5
6
|
import type { ProjectConfigType } from '../types/index.ts';
|
|
6
7
|
/**
|
|
@@ -15,6 +16,7 @@ interface EjsTemplateConfig {
|
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
18
|
* 生成框架项目的通用函数
|
|
19
|
+
* 按照三层嵌套优先级渲染模板:L1 (common) -> L2 (framework) -> L3 (micro-frontend)
|
|
18
20
|
* @param config 项目配置
|
|
19
21
|
* @param ejsConfig EJS 模板配置
|
|
20
22
|
* @throws {Error} 如果模板渲染失败、文件写入失败或配置生成失败
|
|
@@ -1,47 +1,162 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 框架项目生成通用工具
|
|
3
3
|
* 抽离 react.ts 和 vue.ts 的公共逻辑
|
|
4
|
+
* 支持三层嵌套优先级(L1: common, L2: framework, L3: micro-frontend)
|
|
4
5
|
*/
|
|
6
|
+
import fs from 'node:fs';
|
|
5
7
|
import path from 'node:path';
|
|
6
8
|
import { FILE_CONSTANTS } from "../constants/index.js";
|
|
7
9
|
import { renderEjsToFile } from "./ejs.js";
|
|
8
10
|
import { getTemplatesDir } from "./file.js";
|
|
9
|
-
import { renderCommonFeatures, renderFrameworkFeatures } from "./renderFeatures.js";
|
|
11
|
+
import { renderCommonFeatures, renderFrameworkFeatures, renderMicroFrontendFeatures } from "./renderFeatures.js";
|
|
10
12
|
import { renderTemplate, updatePackageJsonMetadata } from "./index.js";
|
|
11
13
|
import { getViteConfigEjsData } from "./viteConfigRender.js";
|
|
12
14
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* @param
|
|
16
|
-
* @
|
|
15
|
+
* 获取 EJS 模板路径(完整优先级查找)
|
|
16
|
+
* 优先级:微前端 feature > 微前端 base > 框架 feature > 框架 base > common feature > common base
|
|
17
|
+
* @param templatesDir 模板根目录
|
|
18
|
+
* @param framework 框架类型
|
|
19
|
+
* @param config 项目配置(用于获取启用的 features)
|
|
20
|
+
* @param templatePath 模板文件路径(相对于 base 目录)
|
|
21
|
+
* @returns EJS 模板文件路径
|
|
17
22
|
*/
|
|
18
|
-
|
|
19
|
-
const {
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
function getEjsTemplatePath(templatesDir, framework, config, templatePath) {
|
|
24
|
+
const { microFrontend, microFrontendEngine } = config;
|
|
25
|
+
// 获取所有启用的 features(包括 UI 库)
|
|
26
|
+
const enabledFeatures = [];
|
|
27
|
+
for (const [key, value] of Object.entries(config)) {
|
|
28
|
+
if (value === true && typeof key === 'string') {
|
|
29
|
+
enabledFeatures.push(key);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (config.uiLibrary) {
|
|
33
|
+
enabledFeatures.push(config.uiLibrary);
|
|
34
|
+
}
|
|
35
|
+
// 1. 微前端 feature(按优先级顺序检查每个启用的 feature)
|
|
36
|
+
if (microFrontend && microFrontendEngine) {
|
|
37
|
+
for (const feature of enabledFeatures) {
|
|
38
|
+
const microFrontendFeaturePath = path.join(templatesDir, framework, 'micro-frontends', microFrontendEngine, 'features', feature, templatePath);
|
|
39
|
+
if (fs.existsSync(microFrontendFeaturePath)) {
|
|
40
|
+
return microFrontendFeaturePath;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// 2. 微前端 base
|
|
45
|
+
if (microFrontend && microFrontendEngine) {
|
|
46
|
+
const microFrontendBasePath = path.join(templatesDir, framework, 'micro-frontends', microFrontendEngine, 'base', templatePath);
|
|
47
|
+
if (fs.existsSync(microFrontendBasePath)) {
|
|
48
|
+
return microFrontendBasePath;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 3. 框架 feature(按优先级顺序检查每个启用的 feature)
|
|
52
|
+
for (const feature of enabledFeatures) {
|
|
53
|
+
const frameworkFeaturePath = path.join(templatesDir, framework, 'features', feature, templatePath);
|
|
54
|
+
if (fs.existsSync(frameworkFeaturePath)) {
|
|
55
|
+
return frameworkFeaturePath;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// 4. 框架 base
|
|
59
|
+
const frameworkBasePath = path.join(templatesDir, framework, 'base', templatePath);
|
|
60
|
+
if (fs.existsSync(frameworkBasePath)) {
|
|
61
|
+
return frameworkBasePath;
|
|
62
|
+
}
|
|
63
|
+
// 5. common feature(按优先级顺序检查每个启用的 feature)
|
|
64
|
+
for (const feature of enabledFeatures) {
|
|
65
|
+
const commonFeaturePath = path.join(templatesDir, 'common', 'features', feature, templatePath);
|
|
66
|
+
if (fs.existsSync(commonFeaturePath)) {
|
|
67
|
+
return commonFeaturePath;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// 6. common base(最终回退)
|
|
71
|
+
return path.join(templatesDir, 'common', 'base', templatePath);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 渲染所有基础模板(base 模板)
|
|
75
|
+
* 按照三层嵌套优先级渲染:L1 (common) -> L2 (framework) -> L3 (micro-frontend)
|
|
76
|
+
* @param templatesDir 模板根目录
|
|
77
|
+
* @param framework 框架类型
|
|
78
|
+
* @param microFrontend 是否启用微前端
|
|
79
|
+
* @param microFrontendEngine 微前端引擎类型
|
|
80
|
+
* @param targetDir 目标目录
|
|
81
|
+
* @throws {Error} 如果模板渲染失败
|
|
82
|
+
*/
|
|
83
|
+
function renderBaseTemplates(templatesDir, framework, microFrontend, microFrontendEngine, targetDir) {
|
|
84
|
+
// 1. 渲染 L1: 公共基础模板(通用层)
|
|
22
85
|
renderTemplate(path.join(templatesDir, 'common', 'base'), targetDir);
|
|
23
|
-
// 2.
|
|
24
|
-
renderCommonFeatures(config, targetDir);
|
|
25
|
-
// 3. 渲染 L1 框架基础模板
|
|
86
|
+
// 2. 渲染 L2: 框架基础模板(框架标准层)
|
|
26
87
|
renderTemplate(path.join(templatesDir, framework, 'base'), targetDir);
|
|
27
|
-
//
|
|
88
|
+
// 3. 渲染 L3: 微前端基础模板(架构增强层)- 按需覆盖
|
|
89
|
+
if (microFrontend && microFrontendEngine) {
|
|
90
|
+
const microFrontendPath = path.join(templatesDir, framework, 'micro-frontends', microFrontendEngine, 'base');
|
|
91
|
+
renderTemplate(microFrontendPath, targetDir);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 渲染所有特性模板(features)
|
|
96
|
+
* 按照三层嵌套优先级渲染:common features -> framework features -> micro-frontend features
|
|
97
|
+
* @param config 项目配置
|
|
98
|
+
* @param targetDir 目标目录
|
|
99
|
+
* @throws {Error} 如果特性渲染失败
|
|
100
|
+
*/
|
|
101
|
+
function renderAllFeatures(config, targetDir) {
|
|
102
|
+
// 1. 渲染公共特性模板
|
|
103
|
+
renderCommonFeatures(config, targetDir);
|
|
104
|
+
// 2. 渲染框架特性模板
|
|
28
105
|
renderFrameworkFeatures(config, targetDir);
|
|
29
|
-
//
|
|
106
|
+
// 3. 渲染微前端专属的 features(覆盖标准 features)
|
|
107
|
+
if (config.microFrontend && config.microFrontendEngine) {
|
|
108
|
+
renderMicroFrontendFeatures(config, targetDir, config.microFrontendEngine);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 渲染所有 EJS 模板
|
|
113
|
+
* 包括主入口文件和 vite.config.ts,按照完整优先级查找模板
|
|
114
|
+
* @param templatesDir 模板根目录
|
|
115
|
+
* @param framework 框架类型
|
|
116
|
+
* @param config 项目配置
|
|
117
|
+
* @param ejsConfig EJS 模板配置
|
|
118
|
+
* @param targetDir 目标目录
|
|
119
|
+
* @throws {Error} 如果 EJS 模板渲染失败
|
|
120
|
+
*/
|
|
121
|
+
function renderEjsTemplates(templatesDir, framework, config, ejsConfig, targetDir) {
|
|
122
|
+
// 准备 EJS 数据
|
|
30
123
|
const ejsData = {
|
|
31
124
|
i18n: config.i18n,
|
|
32
125
|
sentry: config.sentry,
|
|
33
|
-
qiankun: config.qiankun,
|
|
34
126
|
routeMode: config.routeMode,
|
|
35
127
|
uiLibrary: config.uiLibrary,
|
|
128
|
+
// Store management features
|
|
129
|
+
pinia: config.pinia,
|
|
130
|
+
zustand: config.zustand,
|
|
131
|
+
// Router features (derived from routeMode)
|
|
132
|
+
hasRouter: config.manualRoutes || config.pageRoutes,
|
|
36
133
|
};
|
|
37
|
-
|
|
38
|
-
|
|
134
|
+
// 渲染主入口文件 EJS 模板(完整优先级查找)
|
|
135
|
+
const mainTemplatePath = getEjsTemplatePath(templatesDir, framework, config, ejsConfig.mainTemplate);
|
|
136
|
+
renderEjsToFile(mainTemplatePath, path.join(targetDir, ejsConfig.mainOutput), ejsData);
|
|
39
137
|
// Router 已通过 feature 覆盖实现(manualRoutes/pageRoutes),不再使用 EJS
|
|
40
|
-
//
|
|
138
|
+
// 渲染 vite.config.ts(使用 EJS 模板,完整优先级查找)
|
|
41
139
|
const viteConfigEjsData = getViteConfigEjsData(config);
|
|
42
|
-
const
|
|
43
|
-
renderEjsToFile(
|
|
44
|
-
|
|
140
|
+
const viteConfigTemplatePath = getEjsTemplatePath(templatesDir, framework, config, 'vite.config.ts.ejs');
|
|
141
|
+
renderEjsToFile(viteConfigTemplatePath, path.join(targetDir, 'vite.config.ts'), viteConfigEjsData);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* 生成框架项目的通用函数
|
|
145
|
+
* 按照三层嵌套优先级渲染模板:L1 (common) -> L2 (framework) -> L3 (micro-frontend)
|
|
146
|
+
* @param config 项目配置
|
|
147
|
+
* @param ejsConfig EJS 模板配置
|
|
148
|
+
* @throws {Error} 如果模板渲染失败、文件写入失败或配置生成失败
|
|
149
|
+
*/
|
|
150
|
+
export function generateFrameworkProject(config, ejsConfig) {
|
|
151
|
+
const { targetDir, framework, microFrontend, microFrontendEngine } = config;
|
|
152
|
+
const templatesDir = getTemplatesDir();
|
|
153
|
+
// 1. 渲染所有基础模板(base 模板)
|
|
154
|
+
renderBaseTemplates(templatesDir, framework, microFrontend, microFrontendEngine, targetDir);
|
|
155
|
+
// 2. 渲染所有特性模板(features)
|
|
156
|
+
renderAllFeatures(config, targetDir);
|
|
157
|
+
// 3. 渲染所有 EJS 模板
|
|
158
|
+
renderEjsTemplates(templatesDir, framework, config, ejsConfig, targetDir);
|
|
159
|
+
// 4. 更新 package.json 的元数据字段
|
|
45
160
|
const packageJsonPath = path.join(targetDir, FILE_CONSTANTS.PACKAGE_JSON);
|
|
46
161
|
updatePackageJsonMetadata(packageJsonPath, config.projectName, config.description, config.author, config.packageManager);
|
|
47
162
|
}
|
package/dist/utils/prompts.js
CHANGED
|
@@ -6,6 +6,7 @@ import fs from 'node:fs';
|
|
|
6
6
|
import process from 'node:process';
|
|
7
7
|
import inquirer from 'inquirer';
|
|
8
8
|
import { getDefaultAuthor } from "./npmConfig.js";
|
|
9
|
+
import { getRouteModeFeatures } from "./routeModeMapping.js";
|
|
9
10
|
/**
|
|
10
11
|
* 收集项目配置信息
|
|
11
12
|
* @param projectName 项目名称(可选)
|
|
@@ -119,8 +120,8 @@ export async function collectProjectConfig(projectName) {
|
|
|
119
120
|
name: 'routeMode',
|
|
120
121
|
message: '选择路由模式:',
|
|
121
122
|
choices: [
|
|
122
|
-
{ name: '文件系统路由 (vite-plugin-pages)', value: '
|
|
123
|
-
{ name: '手动配置路由', value: '
|
|
123
|
+
{ name: '文件系统路由 (vite-plugin-pages)', value: 'pageRoutes' },
|
|
124
|
+
{ name: '手动配置路由', value: 'manualRoutes' },
|
|
124
125
|
],
|
|
125
126
|
},
|
|
126
127
|
// 是否启用国际化
|
|
@@ -130,6 +131,25 @@ export async function collectProjectConfig(projectName) {
|
|
|
130
131
|
message: '是否启用国际化 (i18n)?',
|
|
131
132
|
default: true,
|
|
132
133
|
},
|
|
134
|
+
// 是否启用微前端
|
|
135
|
+
{
|
|
136
|
+
type: 'confirm',
|
|
137
|
+
name: 'microFrontend',
|
|
138
|
+
message: '是否启用微前端支持?',
|
|
139
|
+
default: false,
|
|
140
|
+
},
|
|
141
|
+
// 微前端引擎选择
|
|
142
|
+
{
|
|
143
|
+
type: 'list',
|
|
144
|
+
name: 'microFrontendEngine',
|
|
145
|
+
message: '选择微前端引擎:',
|
|
146
|
+
choices: [
|
|
147
|
+
{ name: 'qiankun (阿里开源)', value: 'qiankun' },
|
|
148
|
+
// TODO: 还没有,后续可考虑接入
|
|
149
|
+
// { name: 'micro-app (京东开源)', value: 'micro-app' },
|
|
150
|
+
],
|
|
151
|
+
when: (answers) => answers.microFrontend === true,
|
|
152
|
+
},
|
|
133
153
|
// 是否启用错误监控
|
|
134
154
|
{
|
|
135
155
|
type: 'confirm',
|
|
@@ -165,20 +185,30 @@ export async function collectProjectConfig(projectName) {
|
|
|
165
185
|
},
|
|
166
186
|
]);
|
|
167
187
|
const targetDir = `${process.cwd()}/${answers.projectName}`;
|
|
188
|
+
// 根据框架确定状态管理 feature
|
|
189
|
+
const isPinia = answers.framework === 'vue';
|
|
190
|
+
const isZustand = answers.framework === 'react';
|
|
191
|
+
// 根据路由模式获取对应的布尔特征配置
|
|
192
|
+
const routeMode = answers.routeMode;
|
|
193
|
+
const routeModeFeatures = getRouteModeFeatures(routeMode);
|
|
168
194
|
return {
|
|
169
195
|
projectName: answers.projectName,
|
|
170
196
|
description: answers.description,
|
|
171
197
|
author: answers.author,
|
|
172
198
|
framework: answers.framework,
|
|
173
199
|
uiLibrary: answers.uiLibrary,
|
|
174
|
-
routeMode
|
|
175
|
-
|
|
176
|
-
|
|
200
|
+
routeMode,
|
|
201
|
+
// feature 名称与目录名称一致
|
|
202
|
+
pinia: isPinia,
|
|
203
|
+
zustand: isZustand,
|
|
204
|
+
manualRoutes: routeModeFeatures.manualRoutes,
|
|
205
|
+
pageRoutes: routeModeFeatures.pageRoutes,
|
|
177
206
|
i18n: answers.i18n,
|
|
178
|
-
|
|
207
|
+
microFrontend: answers.microFrontend || false,
|
|
208
|
+
microFrontendEngine: answers.microFrontendEngine,
|
|
179
209
|
sentry: answers.sentry,
|
|
180
210
|
eslint: answers.eslint,
|
|
181
|
-
|
|
211
|
+
husky: answers.gitHooks,
|
|
182
212
|
packageManager: answers.packageManager,
|
|
183
213
|
targetDir,
|
|
184
214
|
};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Features 渲染工具
|
|
3
3
|
* 统一处理 features 的渲染逻辑
|
|
4
|
+
* 配置名称与 feature 目录名称完全一致,无需映射
|
|
5
|
+
* 通过文件系统扫描自动发现 features,无需维护常量
|
|
4
6
|
*/
|
|
5
|
-
import type { ProjectConfigType } from '../types/index.ts';
|
|
7
|
+
import type { FrameworkType, ProjectConfigType } from '../types/index.ts';
|
|
6
8
|
/**
|
|
7
9
|
* 渲染框架特定的 features
|
|
10
|
+
* 通过文件系统扫描自动发现并渲染 features
|
|
8
11
|
* @param config 项目配置
|
|
9
12
|
* @param targetDir 目标目录
|
|
10
13
|
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
@@ -12,8 +15,42 @@ import type { ProjectConfigType } from '../types/index.ts';
|
|
|
12
15
|
export declare function renderFrameworkFeatures(config: ProjectConfigType, targetDir: string): void;
|
|
13
16
|
/**
|
|
14
17
|
* 渲染公共 features
|
|
18
|
+
* 通过文件系统扫描自动发现并渲染公共 features
|
|
15
19
|
* @param config 项目配置
|
|
16
20
|
* @param targetDir 目标目录
|
|
17
21
|
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
18
22
|
*/
|
|
19
23
|
export declare function renderCommonFeatures(config: ProjectConfigType, targetDir: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* 验证微前端引擎是否存在
|
|
26
|
+
* @param framework 框架类型
|
|
27
|
+
* @param engine 微前端引擎名称
|
|
28
|
+
* @returns 引擎是否存在
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateMicroFrontendEngine(framework: FrameworkType, engine: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* 获取可用的公共 features(用于测试和文档生成)
|
|
33
|
+
* @returns 公共 feature 名称数组
|
|
34
|
+
*/
|
|
35
|
+
export declare function getAvailableCommonFeatures(): string[];
|
|
36
|
+
/**
|
|
37
|
+
* 获取可用的框架 features(用于测试和文档生成)
|
|
38
|
+
* @param framework 框架类型
|
|
39
|
+
* @returns 框架 feature 名称数组
|
|
40
|
+
*/
|
|
41
|
+
export declare function getAvailableFrameworkFeatures(framework: FrameworkType): string[];
|
|
42
|
+
/**
|
|
43
|
+
* 获取可用的微前端引擎(用于测试和文档生成)
|
|
44
|
+
* @param framework 框架类型
|
|
45
|
+
* @returns 微前端引擎名称数组
|
|
46
|
+
*/
|
|
47
|
+
export declare function getAvailableMicroFrontendEngines(framework: FrameworkType): string[];
|
|
48
|
+
/**
|
|
49
|
+
* 渲染微前端专属的 features(覆盖标准 features)
|
|
50
|
+
* 只渲染文件系统中存在的微前端 features,实现按需覆盖
|
|
51
|
+
* @param config 项目配置
|
|
52
|
+
* @param targetDir 目标目录
|
|
53
|
+
* @param microFrontendEngine 微前端引擎类型
|
|
54
|
+
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
55
|
+
*/
|
|
56
|
+
export declare function renderMicroFrontendFeatures(config: ProjectConfigType, targetDir: string, microFrontendEngine: string): void;
|
|
@@ -1,76 +1,160 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Features 渲染工具
|
|
3
3
|
* 统一处理 features 的渲染逻辑
|
|
4
|
+
* 配置名称与 feature 目录名称完全一致,无需映射
|
|
5
|
+
* 通过文件系统扫描自动发现 features,无需维护常量
|
|
4
6
|
*/
|
|
7
|
+
import fs from 'fs-extra';
|
|
5
8
|
import path from 'node:path';
|
|
6
9
|
import { getTemplatesDir } from "./file.js";
|
|
7
10
|
import { renderTemplate } from "./renderTemplate.js";
|
|
8
|
-
import { getCommonFeatureMap, getConfigToFeatureMap, getRouteModeFeature, getUILibraryFeature, } from "./featureMapping.js";
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
11
|
-
* @param
|
|
12
|
-
* @
|
|
13
|
-
* @returns 是否适用
|
|
12
|
+
* 扫描指定目录下的所有 feature 目录
|
|
13
|
+
* @param baseDir 基础目录
|
|
14
|
+
* @returns feature 名称数组
|
|
14
15
|
*/
|
|
15
|
-
function
|
|
16
|
-
if (
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
if (framework === 'react') {
|
|
20
|
-
return uiLibrary === 'ant-design';
|
|
16
|
+
function scanFeatures(baseDir) {
|
|
17
|
+
if (!fs.existsSync(baseDir)) {
|
|
18
|
+
return [];
|
|
21
19
|
}
|
|
22
|
-
return
|
|
20
|
+
return fs.readdirSync(baseDir).filter((item) => {
|
|
21
|
+
const itemPath = path.join(baseDir, item);
|
|
22
|
+
return fs.statSync(itemPath).isDirectory();
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 获取公共 features 列表(从文件系统扫描)
|
|
27
|
+
* @returns 公共 feature 名称数组
|
|
28
|
+
*/
|
|
29
|
+
function getCommonFeatures() {
|
|
30
|
+
const templatesDir = getTemplatesDir();
|
|
31
|
+
const commonFeaturesDir = path.join(templatesDir, 'common', 'features');
|
|
32
|
+
return scanFeatures(commonFeaturesDir);
|
|
23
33
|
}
|
|
24
34
|
/**
|
|
25
|
-
*
|
|
35
|
+
* 获取框架 features 列表(从文件系统扫描)
|
|
36
|
+
* @param framework 框架类型
|
|
37
|
+
* @returns 框架 feature 名称数组
|
|
38
|
+
*/
|
|
39
|
+
function getFrameworkFeatures(framework) {
|
|
40
|
+
const templatesDir = getTemplatesDir();
|
|
41
|
+
const frameworkFeaturesDir = path.join(templatesDir, framework, 'features');
|
|
42
|
+
return scanFeatures(frameworkFeaturesDir);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 获取微前端引擎列表(从文件系统扫描)
|
|
46
|
+
* @param framework 框架类型
|
|
47
|
+
* @returns 微前端引擎名称数组
|
|
48
|
+
*/
|
|
49
|
+
function getMicroFrontendEngines(framework) {
|
|
50
|
+
const templatesDir = getTemplatesDir();
|
|
51
|
+
const microFrontendsDir = path.join(templatesDir, framework, 'micro-frontends');
|
|
52
|
+
return scanFeatures(microFrontendsDir);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 渲染框架特定的 features
|
|
56
|
+
* 通过文件系统扫描自动发现并渲染 features
|
|
26
57
|
* @param config 项目配置
|
|
27
58
|
* @param targetDir 目标目录
|
|
28
|
-
* @param templatesDir 模板目录
|
|
29
59
|
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
30
60
|
*/
|
|
31
|
-
function
|
|
61
|
+
export function renderFrameworkFeatures(config, targetDir) {
|
|
62
|
+
const templatesDir = getTemplatesDir();
|
|
32
63
|
const { framework, uiLibrary } = config;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
64
|
+
// 从文件系统扫描获取所有框架 features
|
|
65
|
+
const availableFeatures = getFrameworkFeatures(framework);
|
|
66
|
+
// 遍历配置对象,渲染所有值为 true 且存在于文件系统的 features
|
|
67
|
+
for (const [key, value] of Object.entries(config)) {
|
|
68
|
+
// 如果配置值为 true 且 feature 目录存在,则渲染
|
|
69
|
+
if (value === true && availableFeatures.includes(key)) {
|
|
70
|
+
const featurePath = path.join(templatesDir, framework, 'features', key);
|
|
71
|
+
renderTemplate(featurePath, targetDir);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// UI 库单独处理(配置值 === feature 目录名)
|
|
75
|
+
if (uiLibrary && availableFeatures.includes(uiLibrary)) {
|
|
76
|
+
renderTemplate(path.join(templatesDir, framework, 'features', uiLibrary), targetDir);
|
|
36
77
|
}
|
|
37
78
|
}
|
|
38
79
|
/**
|
|
39
|
-
*
|
|
80
|
+
* 渲染公共 features
|
|
81
|
+
* 通过文件系统扫描自动发现并渲染公共 features
|
|
40
82
|
* @param config 项目配置
|
|
41
83
|
* @param targetDir 目标目录
|
|
42
84
|
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
43
85
|
*/
|
|
44
|
-
export function
|
|
86
|
+
export function renderCommonFeatures(config, targetDir) {
|
|
45
87
|
const templatesDir = getTemplatesDir();
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
//
|
|
49
|
-
for (const [
|
|
50
|
-
if (
|
|
51
|
-
const featurePath = path.join(templatesDir,
|
|
88
|
+
// 从文件系统扫描获取所有公共 features
|
|
89
|
+
const availableFeatures = getCommonFeatures();
|
|
90
|
+
// 遍历配置对象,渲染所有值为 true 且存在于文件系统的公共 features
|
|
91
|
+
for (const [key, value] of Object.entries(config)) {
|
|
92
|
+
if (value === true && availableFeatures.includes(key)) {
|
|
93
|
+
const featurePath = path.join(templatesDir, 'common', 'features', key);
|
|
52
94
|
renderTemplate(featurePath, targetDir);
|
|
53
95
|
}
|
|
54
96
|
}
|
|
55
|
-
// 路由模式
|
|
56
|
-
const routeModeFeature = getRouteModeFeature(config.routeMode);
|
|
57
|
-
renderTemplate(path.join(templatesDir, framework, 'features', routeModeFeature), targetDir);
|
|
58
|
-
// UI 库
|
|
59
|
-
renderUILibraryFeature(config, targetDir, templatesDir);
|
|
60
97
|
}
|
|
61
98
|
/**
|
|
62
|
-
*
|
|
99
|
+
* 验证微前端引擎是否存在
|
|
100
|
+
* @param framework 框架类型
|
|
101
|
+
* @param engine 微前端引擎名称
|
|
102
|
+
* @returns 引擎是否存在
|
|
103
|
+
*/
|
|
104
|
+
export function validateMicroFrontendEngine(framework, engine) {
|
|
105
|
+
const availableEngines = getMicroFrontendEngines(framework);
|
|
106
|
+
return availableEngines.includes(engine);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 获取可用的公共 features(用于测试和文档生成)
|
|
110
|
+
* @returns 公共 feature 名称数组
|
|
111
|
+
*/
|
|
112
|
+
export function getAvailableCommonFeatures() {
|
|
113
|
+
return getCommonFeatures();
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 获取可用的框架 features(用于测试和文档生成)
|
|
117
|
+
* @param framework 框架类型
|
|
118
|
+
* @returns 框架 feature 名称数组
|
|
119
|
+
*/
|
|
120
|
+
export function getAvailableFrameworkFeatures(framework) {
|
|
121
|
+
return getFrameworkFeatures(framework);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 获取可用的微前端引擎(用于测试和文档生成)
|
|
125
|
+
* @param framework 框架类型
|
|
126
|
+
* @returns 微前端引擎名称数组
|
|
127
|
+
*/
|
|
128
|
+
export function getAvailableMicroFrontendEngines(framework) {
|
|
129
|
+
return getMicroFrontendEngines(framework);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 渲染微前端专属的 features(覆盖标准 features)
|
|
133
|
+
* 只渲染文件系统中存在的微前端 features,实现按需覆盖
|
|
63
134
|
* @param config 项目配置
|
|
64
135
|
* @param targetDir 目标目录
|
|
136
|
+
* @param microFrontendEngine 微前端引擎类型
|
|
65
137
|
* @throws {Error} 如果路径不安全或模板渲染失败
|
|
66
138
|
*/
|
|
67
|
-
export function
|
|
139
|
+
export function renderMicroFrontendFeatures(config, targetDir, microFrontendEngine) {
|
|
68
140
|
const templatesDir = getTemplatesDir();
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
141
|
+
const { framework, uiLibrary } = config;
|
|
142
|
+
const microFrontendFeaturesPath = path.join(templatesDir, framework, 'micro-frontends', microFrontendEngine, 'features');
|
|
143
|
+
// 如果微前端 features 目录不存在,直接返回
|
|
144
|
+
if (!fs.existsSync(microFrontendFeaturesPath)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// 扫描微前端 features 目录
|
|
148
|
+
const availableMicroFrontendFeatures = scanFeatures(microFrontendFeaturesPath);
|
|
149
|
+
// 遍历配置对象,渲染所有值为 true 且存在于微前端 features 的 features
|
|
150
|
+
for (const [key, value] of Object.entries(config)) {
|
|
151
|
+
if (value === true && availableMicroFrontendFeatures.includes(key)) {
|
|
152
|
+
const featurePath = path.join(microFrontendFeaturesPath, key);
|
|
73
153
|
renderTemplate(featurePath, targetDir);
|
|
74
154
|
}
|
|
75
155
|
}
|
|
156
|
+
// UI 库单独处理(如果微前端有 UI 库专属的覆盖)
|
|
157
|
+
if (uiLibrary && availableMicroFrontendFeatures.includes(uiLibrary)) {
|
|
158
|
+
renderTemplate(path.join(microFrontendFeaturesPath, uiLibrary), targetDir);
|
|
159
|
+
}
|
|
76
160
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路由模式映射工具
|
|
3
|
+
* 统一处理路由模式的映射和转换逻辑
|
|
4
|
+
*/
|
|
5
|
+
import type { RouteModeType } from '../types/index.ts';
|
|
6
|
+
/**
|
|
7
|
+
* 根据路由模式获取对应的布尔特征配置
|
|
8
|
+
* @param routeMode 路由模式('pageRoutes' | 'manualRoutes')
|
|
9
|
+
* @returns 包含 manualRoutes 和 pageRoutes 布尔值的对象
|
|
10
|
+
*/
|
|
11
|
+
export declare function getRouteModeFeatures(routeMode: RouteModeType): {
|
|
12
|
+
manualRoutes: boolean;
|
|
13
|
+
pageRoutes: boolean;
|
|
14
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路由模式映射工具
|
|
3
|
+
* 统一处理路由模式的映射和转换逻辑
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 根据路由模式获取对应的布尔特征配置
|
|
7
|
+
* @param routeMode 路由模式('pageRoutes' | 'manualRoutes')
|
|
8
|
+
* @returns 包含 manualRoutes 和 pageRoutes 布尔值的对象
|
|
9
|
+
*/
|
|
10
|
+
export function getRouteModeFeatures(routeMode) {
|
|
11
|
+
return {
|
|
12
|
+
manualRoutes: routeMode === 'manualRoutes',
|
|
13
|
+
pageRoutes: routeMode === 'pageRoutes',
|
|
14
|
+
};
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moluoxixi/create-app",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.410",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Create Vue/React projects with atomic layered architecture",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -73,8 +73,7 @@
|
|
|
73
73
|
"scripts": {
|
|
74
74
|
"dev": "tsx src/index.ts",
|
|
75
75
|
"build": "tsc --build tsconfig.build.json",
|
|
76
|
-
"test": "tsx src/test.ts
|
|
77
|
-
"test:all": "tsx src/test.ts",
|
|
76
|
+
"test": "tsx src/test.ts",
|
|
78
77
|
"type-check": "tsc --noEmit",
|
|
79
78
|
"lint:eslint": "eslint . --fix",
|
|
80
79
|
"submodule:update": "git submodule init && git submodule update --init --recursive",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"packageManager": "pnpm@10.8.0",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "vite",
|
|
12
|
-
"submodule:update": "git submodule init && git submodule update --init --recursive",
|
|
12
|
+
"submodule:update": "git init && git submodule init && git submodule update --init --recursive",
|
|
13
13
|
"prepare": "pnpm submodule:update",
|
|
14
14
|
"build": "vite build --mode production",
|
|
15
15
|
"build:zip": "vite build --mode production && tsx scripts/build.mts",
|