@moluoxixi/create-app 2.0.408 → 2.0.411

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/test.js +168 -87
  2. package/dist/types/features.d.ts +7 -9
  3. package/dist/types/features.js +6 -25
  4. package/dist/types/index.d.ts +20 -13
  5. package/dist/utils/featureMapping.d.ts +5 -26
  6. package/dist/utils/featureMapping.js +24 -68
  7. package/dist/utils/generateFrameworkProject.d.ts +2 -0
  8. package/dist/utils/generateFrameworkProject.js +136 -21
  9. package/dist/utils/prompts.js +37 -7
  10. package/dist/utils/renderFeatures.d.ts +38 -1
  11. package/dist/utils/renderFeatures.js +121 -37
  12. package/dist/utils/routeModeMapping.d.ts +14 -0
  13. package/dist/utils/routeModeMapping.js +15 -0
  14. package/package.json +2 -3
  15. package/templates/common/base/package.json +1 -1
  16. package/templates/common/base/vite.config.ts.ejs +1 -1
  17. package/templates/react/base/package.json +1 -3
  18. package/templates/react/base/src/main.tsx.ejs +16 -43
  19. package/templates/react/features/pageRoutes/package.json +1 -0
  20. package/templates/react/micro-frontends/qiankun/base/package.json +6 -0
  21. package/templates/react/micro-frontends/qiankun/base/src/main.tsx.ejs +83 -0
  22. package/templates/react/micro-frontends/qiankun/base/vite.config.ts.ejs +89 -0
  23. package/templates/vue/base/package.json +1 -5
  24. package/templates/vue/base/src/main.ts.ejs +18 -41
  25. package/templates/vue/features/element-plus/src/layouts/element.vue +1 -4
  26. package/templates/vue/features/manualRoutes/package.json +0 -1
  27. package/templates/vue/features/manualRoutes/src/router/index.ts +11 -12
  28. package/templates/vue/features/manualRoutes/src/router/routes.ts +14 -23
  29. package/templates/vue/features/pageRoutes/package.json +0 -1
  30. package/templates/vue/features/pageRoutes/src/router/index.ts +11 -12
  31. package/templates/vue/features/pinia/node_modules/.bin/tsc +17 -0
  32. package/templates/vue/features/pinia/node_modules/.bin/tsc.CMD +12 -0
  33. package/templates/vue/features/pinia/node_modules/.bin/tsc.ps1 +41 -0
  34. package/templates/vue/features/pinia/node_modules/.bin/tsserver +17 -0
  35. package/templates/vue/features/pinia/node_modules/.bin/tsserver.CMD +12 -0
  36. package/templates/vue/features/pinia/node_modules/.bin/tsserver.ps1 +41 -0
  37. package/templates/vue/features/pinia/package.json +6 -0
  38. package/templates/vue/micro-frontends/qiankun/base/package.json +6 -0
  39. package/templates/vue/micro-frontends/qiankun/base/src/main.ts.ejs +87 -0
  40. package/templates/vue/micro-frontends/qiankun/base/vite.config.ts.ejs +89 -0
  41. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/layouts/element.vue +120 -0
  42. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/jiti +17 -0
  43. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/jiti.CMD +12 -0
  44. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/jiti.ps1 +41 -0
  45. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/sass +17 -0
  46. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/sass.CMD +12 -0
  47. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/sass.ps1 +41 -0
  48. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/terser +17 -0
  49. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/terser.CMD +12 -0
  50. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/terser.ps1 +41 -0
  51. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsc +17 -0
  52. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsc.CMD +12 -0
  53. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsc.ps1 +41 -0
  54. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsserver +17 -0
  55. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsserver.CMD +12 -0
  56. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsserver.ps1 +41 -0
  57. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsx +17 -0
  58. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsx.CMD +12 -0
  59. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/tsx.ps1 +41 -0
  60. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/vite +17 -0
  61. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/vite.CMD +12 -0
  62. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/vite.ps1 +41 -0
  63. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/yaml +17 -0
  64. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/yaml.CMD +12 -0
  65. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/yaml.ps1 +41 -0
  66. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/package.json +5 -0
  67. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/src/router/index.ts +56 -0
  68. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/jiti +17 -0
  69. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/jiti.CMD +12 -0
  70. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/jiti.ps1 +41 -0
  71. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/sass +17 -0
  72. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/sass.CMD +12 -0
  73. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/sass.ps1 +41 -0
  74. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/terser +17 -0
  75. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/terser.CMD +12 -0
  76. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/terser.ps1 +41 -0
  77. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsc +17 -0
  78. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsc.CMD +12 -0
  79. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsc.ps1 +41 -0
  80. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsserver +17 -0
  81. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsserver.CMD +12 -0
  82. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsserver.ps1 +41 -0
  83. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsx +17 -0
  84. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsx.CMD +12 -0
  85. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/tsx.ps1 +41 -0
  86. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/vite +17 -0
  87. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/vite.CMD +12 -0
  88. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/vite.ps1 +41 -0
  89. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/yaml +17 -0
  90. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/yaml.CMD +12 -0
  91. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/yaml.ps1 +41 -0
  92. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/package.json +5 -0
  93. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/src/router/index.ts +57 -0
  94. package/templates/react/base/src/qiankun/index.ts +0 -83
  95. package/templates/react/base/src/stores/user.ts +0 -55
  96. package/templates/vue/base/src/router/layout.vue +0 -15
  97. package/templates/vue/features/manualRoutes/src/stores/index.ts +0 -6
  98. package/templates/vue/features/manualRoutes/src/stores/modules/system.ts +0 -51
  99. package/templates/vue/features/manualRoutes/src/stores/modules/user.ts +0 -41
  100. package/templates/vue/features/pageRoutes/src/stores/index.ts +0 -6
  101. package/templates/vue/features/pageRoutes/src/stores/modules/system.ts +0 -51
  102. package/templates/vue/features/pageRoutes/src/stores/modules/user.ts +0 -41
  103. /package/templates/react/features/{router → manualRoutes}/package.json +0 -0
  104. /package/templates/react/{base → features/zustand}/src/stores/index.ts +0 -0
  105. /package/templates/vue/{base → features/pinia}/src/stores/index.ts +0 -0
  106. /package/templates/vue/{base → features/pinia}/src/stores/modules/system.ts +0 -0
  107. /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
- * @param config 项目配置
15
- * @param ejsConfig EJS 模板配置
16
- * @throws {Error} 如果模板渲染失败、文件写入失败或配置生成失败
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
- export function generateFrameworkProject(config, ejsConfig) {
19
- const { targetDir, framework } = config;
20
- const templatesDir = getTemplatesDir();
21
- // 1. 渲染 L0 公共基础模板
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
- // 4. 渲染 L2 特性模板(统一处理)
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
- // 5. 渲染 EJS 模板
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
- const frameworkBasePath = path.join(templatesDir, framework, 'base');
38
- renderEjsToFile(path.join(frameworkBasePath, ejsConfig.mainTemplate), path.join(targetDir, ejsConfig.mainOutput), ejsData);
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
- // 6. 数据驱动生成 vite.config.ts(使用 EJS 模板)
138
+ // 渲染 vite.config.ts(使用 EJS 模板,完整优先级查找)
41
139
  const viteConfigEjsData = getViteConfigEjsData(config);
42
- const commonBasePath = path.join(templatesDir, 'common', 'base');
43
- renderEjsToFile(path.join(commonBasePath, 'vite.config.ts.ejs'), path.join(targetDir, 'vite.config.ts'), viteConfigEjsData);
44
- // 7. 更新 package.json 的元数据字段
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
  }
@@ -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: 'file-system' },
123
- { name: '手动配置路由', value: 'manual' },
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: answers.routeMode || 'manual',
175
- router: true, // 路由已内置
176
- stateManagement: true, // 状态管理已内置
200
+ routeMode,
201
+ // feature 名称与目录名称一致
202
+ pinia: isPinia,
203
+ zustand: isZustand,
204
+ manualRoutes: routeModeFeatures.manualRoutes,
205
+ pageRoutes: routeModeFeatures.pageRoutes,
177
206
  i18n: answers.i18n,
178
- qiankun: true, // 微前端已内置
207
+ microFrontend: answers.microFrontend || false,
208
+ microFrontendEngine: answers.microFrontendEngine,
179
209
  sentry: answers.sentry,
180
210
  eslint: answers.eslint,
181
- gitHooks: answers.gitHooks,
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
- * 检查 UI 库是否适用于指定框架
11
- * @param framework 框架类型
12
- * @param uiLibrary UI 库类型
13
- * @returns 是否适用
12
+ * 扫描指定目录下的所有 feature 目录
13
+ * @param baseDir 基础目录
14
+ * @returns feature 名称数组
14
15
  */
15
- function isUILibrarySupported(framework, uiLibrary) {
16
- if (framework === 'vue') {
17
- return uiLibrary === 'element-plus' || uiLibrary === 'ant-design-vue';
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 false;
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
- * 渲染 UI 库特性模板
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 renderUILibraryFeature(config, targetDir, templatesDir) {
61
+ export function renderFrameworkFeatures(config, targetDir) {
62
+ const templatesDir = getTemplatesDir();
32
63
  const { framework, uiLibrary } = config;
33
- if (isUILibrarySupported(framework, uiLibrary)) {
34
- const uiLibraryFeature = getUILibraryFeature(uiLibrary);
35
- renderTemplate(path.join(templatesDir, framework, 'features', uiLibraryFeature), targetDir);
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
- * 渲染框架特定的 features
80
+ * 渲染公共 features
81
+ * 通过文件系统扫描自动发现并渲染公共 features
40
82
  * @param config 项目配置
41
83
  * @param targetDir 目标目录
42
84
  * @throws {Error} 如果路径不安全或模板渲染失败
43
85
  */
44
- export function renderFrameworkFeatures(config, targetDir) {
86
+ export function renderCommonFeatures(config, targetDir) {
45
87
  const templatesDir = getTemplatesDir();
46
- const framework = config.framework;
47
- const featureMap = getConfigToFeatureMap(framework);
48
- // 统一处理布尔类型的 features
49
- for (const [configKey, featureName] of Object.entries(featureMap)) {
50
- if (config[configKey] === true) {
51
- const featurePath = path.join(templatesDir, framework, 'features', featureName);
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
- * 渲染公共 features
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 renderCommonFeatures(config, targetDir) {
139
+ export function renderMicroFrontendFeatures(config, targetDir, microFrontendEngine) {
68
140
  const templatesDir = getTemplatesDir();
69
- const commonFeatureMap = getCommonFeatureMap();
70
- for (const [configKey, featureName] of Object.entries(commonFeatureMap)) {
71
- if (config[configKey] === true) {
72
- const featurePath = path.join(templatesDir, 'common', 'features', featureName);
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.408",
3
+ "version": "2.0.411",
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 --min",
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",
@@ -27,7 +27,7 @@ export default ViteConfig(
27
27
  <% } else if (framework === 'react') { -%>
28
28
  react: true,
29
29
  <% } -%>
30
- <% if (routeMode === 'file-system') { -%>
30
+ <% if (routeMode === 'pageRoutes') { -%>
31
31
  pageRoutes: true,
32
32
  <% } -%>
33
33
  viteConfig: {
@@ -5,9 +5,7 @@
5
5
  },
6
6
  "dependencies": {
7
7
  "react": "^18.3.1",
8
- "react-dom": "^18.3.1",
9
- "vite-plugin-qiankun": "^1.0.15",
10
- "@remix-run/router": "^1.23.0"
8
+ "react-dom": "^18.3.1"
11
9
  },
12
10
  "devDependencies": {
13
11
  "@moluoxixi/css-module-global-root-plugin": "latest",