@moluoxixi/create-app 2.0.413 → 2.0.415

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 (193) hide show
  1. package/README.md +57 -1
  2. package/dist/commands/create.js +1 -1
  3. package/dist/core/feature.d.ts +80 -0
  4. package/dist/core/feature.js +252 -0
  5. package/dist/core/index.d.ts +6 -0
  6. package/dist/core/index.js +6 -0
  7. package/dist/core/prompts.d.ts +17 -0
  8. package/dist/core/prompts.js +235 -0
  9. package/dist/core/template.d.ts +22 -0
  10. package/dist/core/template.js +177 -0
  11. package/dist/generators/index.d.ts +0 -2
  12. package/dist/generators/index.js +0 -2
  13. package/dist/generators/project.d.ts +1 -0
  14. package/dist/generators/project.js +66 -13
  15. package/dist/generators/react.d.ts +5 -5
  16. package/dist/generators/react.js +6 -9
  17. package/dist/generators/vue.d.ts +5 -5
  18. package/dist/generators/vue.js +6 -9
  19. package/dist/test.d.ts +0 -4
  20. package/dist/test.js +32 -17
  21. package/dist/types/index.d.ts +25 -26
  22. package/dist/types/index.js +2 -3
  23. package/dist/utils/featureMapping.js +6 -3
  24. package/dist/utils/generateFrameworkProject.d.ts +10 -20
  25. package/dist/utils/generateFrameworkProject.js +32 -127
  26. package/dist/utils/index.d.ts +1 -6
  27. package/dist/utils/index.js +1 -6
  28. package/dist/utils/prompts.js +7 -3
  29. package/package.json +3 -9
  30. package/templates/common/base/package.json +3 -1
  31. package/templates/common/base/vite/index.ts +53 -0
  32. package/templates/common/base/vite.config.ts +56 -0
  33. package/templates/common/features/husky/node_modules/.bin/tsc +17 -0
  34. package/templates/common/features/husky/node_modules/.bin/tsc.CMD +12 -0
  35. package/templates/common/features/husky/node_modules/.bin/tsc.ps1 +41 -0
  36. package/templates/common/features/husky/node_modules/.bin/tsserver +17 -0
  37. package/templates/common/features/husky/node_modules/.bin/tsserver.CMD +12 -0
  38. package/templates/common/features/husky/node_modules/.bin/tsserver.ps1 +41 -0
  39. package/templates/react/base/src/main/index.ts +34 -0
  40. package/templates/react/base/src/main.tsx +34 -0
  41. package/templates/react/base/tsconfig.app.json +1 -0
  42. package/templates/react/base/tsconfig.node.json +1 -0
  43. package/templates/react/features/ant-design/package.json +2 -1
  44. package/templates/react/features/ant-design/src/main/features/ant-design.ts +21 -0
  45. package/templates/react/features/i18n/package.json +2 -1
  46. package/templates/react/features/i18n/src/main/features/i18n.ts +19 -0
  47. package/templates/react/features/manualRoutes/package.json +1 -0
  48. package/templates/react/features/sentry/package.json +2 -1
  49. package/templates/react/features/sentry/src/main/features/sentry.ts +20 -0
  50. package/templates/react/features/sentry/vite/features/sentry.ts +39 -0
  51. package/templates/react/features/zustand/src/apis/types/user.ts +39 -0
  52. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/browserslist +17 -0
  53. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/browserslist.CMD +12 -0
  54. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/browserslist.ps1 +41 -0
  55. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/jiti +17 -0
  56. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/jiti.CMD +12 -0
  57. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/jiti.ps1 +41 -0
  58. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/parser +17 -0
  59. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/parser.CMD +12 -0
  60. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/parser.ps1 +41 -0
  61. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/rollup +17 -0
  62. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/rollup.CMD +12 -0
  63. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/rollup.ps1 +41 -0
  64. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/sass +17 -0
  65. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/sass.CMD +12 -0
  66. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/sass.ps1 +41 -0
  67. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/terser +17 -0
  68. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/terser.CMD +12 -0
  69. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/terser.ps1 +41 -0
  70. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsc +17 -0
  71. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsc.CMD +12 -0
  72. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsc.ps1 +41 -0
  73. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsserver +17 -0
  74. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsserver.CMD +12 -0
  75. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsserver.ps1 +41 -0
  76. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsx +17 -0
  77. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsx.CMD +12 -0
  78. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/tsx.ps1 +41 -0
  79. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/vite +17 -0
  80. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/vite.CMD +12 -0
  81. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/vite.ps1 +41 -0
  82. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/yaml +17 -0
  83. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/yaml.CMD +12 -0
  84. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/yaml.ps1 +41 -0
  85. package/templates/react/micro-frontends/qiankun/base/package.json +7 -2
  86. package/templates/react/micro-frontends/qiankun/base/src/main/index.ts +34 -0
  87. package/templates/react/micro-frontends/qiankun/base/src/{main.tsx.ejs → main.tsx} +13 -27
  88. package/templates/react/micro-frontends/qiankun/base/vite/index.ts +53 -0
  89. package/templates/react/micro-frontends/qiankun/base/vite.config.ts +58 -0
  90. package/templates/vue/base/src/main/index.ts +36 -0
  91. package/templates/vue/base/src/main.ts +34 -0
  92. package/templates/vue/base/tsconfig.app.json +2 -1
  93. package/templates/vue/base/tsconfig.node.json +2 -1
  94. package/templates/vue/features/ant-design-vue/package.json +3 -1
  95. package/templates/vue/features/ant-design-vue/src/main/features/ant-design-vue.ts +18 -0
  96. package/templates/vue/features/element-plus/package.json +5 -1
  97. package/templates/vue/features/element-plus/src/main/features/element-plus.ts +23 -0
  98. package/templates/vue/features/element-plus/src/stores/index.ts +6 -0
  99. package/templates/vue/features/element-plus/src/stores/modules/system.ts +51 -0
  100. package/templates/vue/features/element-plus/vite/features/element-plus.ts +35 -0
  101. package/templates/vue/features/i18n/package.json +3 -1
  102. package/templates/vue/features/i18n/src/main/features/i18n.ts +19 -0
  103. package/templates/vue/features/manualRoutes/package.json +7 -1
  104. package/templates/vue/features/manualRoutes/src/layouts/index.ts +26 -0
  105. package/templates/vue/features/manualRoutes/src/stores/index.ts +6 -0
  106. package/templates/vue/features/manualRoutes/src/stores/modules/system.ts +51 -0
  107. package/templates/vue/features/pageRoutes/package.json +7 -1
  108. package/templates/vue/features/pageRoutes/src/layouts/index.ts +26 -0
  109. package/templates/vue/features/pageRoutes/src/stores/index.ts +6 -0
  110. package/templates/vue/features/pageRoutes/src/stores/modules/system.ts +51 -0
  111. package/templates/vue/features/pinia/package.json +3 -1
  112. package/templates/vue/features/pinia/src/main/features/pinia.ts +19 -0
  113. package/templates/vue/features/sentry/package.json +4 -2
  114. package/templates/vue/features/sentry/src/main/features/sentry.ts +22 -0
  115. package/templates/vue/features/sentry/vite/features/sentry.ts +39 -0
  116. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/browserslist +17 -0
  117. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/browserslist.CMD +12 -0
  118. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/browserslist.ps1 +41 -0
  119. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/jiti +17 -0
  120. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/jiti.CMD +12 -0
  121. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/jiti.ps1 +41 -0
  122. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/parser +17 -0
  123. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/parser.CMD +12 -0
  124. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/parser.ps1 +41 -0
  125. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/rollup +17 -0
  126. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/rollup.CMD +12 -0
  127. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/rollup.ps1 +41 -0
  128. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/sass +17 -0
  129. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/sass.CMD +12 -0
  130. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/sass.ps1 +41 -0
  131. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/terser +17 -0
  132. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/terser.CMD +12 -0
  133. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/terser.ps1 +41 -0
  134. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsc +17 -0
  135. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsc.CMD +12 -0
  136. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsc.ps1 +41 -0
  137. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsserver +17 -0
  138. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsserver.CMD +12 -0
  139. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsserver.ps1 +41 -0
  140. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsx +17 -0
  141. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsx.CMD +12 -0
  142. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/tsx.ps1 +41 -0
  143. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/vite +17 -0
  144. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/vite.CMD +12 -0
  145. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/vite.ps1 +41 -0
  146. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/yaml +17 -0
  147. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/yaml.CMD +12 -0
  148. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/yaml.ps1 +41 -0
  149. package/templates/vue/micro-frontends/qiankun/base/package.json +7 -2
  150. package/templates/vue/micro-frontends/qiankun/base/src/main/index.ts +36 -0
  151. package/templates/vue/micro-frontends/qiankun/base/src/{main.ts.ejs → main.ts} +11 -28
  152. package/templates/vue/micro-frontends/qiankun/base/vite/index.ts +53 -0
  153. package/templates/vue/micro-frontends/qiankun/base/vite.config.ts +59 -0
  154. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/jiti +17 -0
  155. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/jiti.CMD +12 -0
  156. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/jiti.ps1 +41 -0
  157. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/sass +17 -0
  158. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/sass.CMD +12 -0
  159. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/sass.ps1 +41 -0
  160. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/terser +17 -0
  161. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/terser.CMD +12 -0
  162. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/terser.ps1 +41 -0
  163. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsc +17 -0
  164. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsc.CMD +12 -0
  165. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsc.ps1 +41 -0
  166. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsserver +17 -0
  167. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsserver.CMD +12 -0
  168. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsserver.ps1 +41 -0
  169. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsx +17 -0
  170. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsx.CMD +12 -0
  171. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/tsx.ps1 +41 -0
  172. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/vite +17 -0
  173. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/vite.CMD +12 -0
  174. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/vite.ps1 +41 -0
  175. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/yaml +17 -0
  176. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/yaml.CMD +12 -0
  177. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/yaml.ps1 +41 -0
  178. package/templates/vue/micro-frontends/qiankun/features/element-plus/package.json +10 -0
  179. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/components/SubMenu/index.ts +8 -0
  180. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/components/SubMenu/src/_types/index.ts +1 -0
  181. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/components/SubMenu/src/_types/props.ts +16 -0
  182. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/components/SubMenu/src/index.vue +60 -0
  183. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/main/features/element-plus.ts +24 -0
  184. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/stores/index.ts +6 -0
  185. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/stores/modules/system.ts +51 -0
  186. package/templates/vue/micro-frontends/qiankun/features/element-plus/vite/features/element-plus.ts +35 -0
  187. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/package.json +6 -1
  188. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/package.json +6 -1
  189. package/templates/common/base/vite.config.ts.ejs +0 -85
  190. package/templates/react/base/src/main.tsx.ejs +0 -56
  191. package/templates/react/micro-frontends/qiankun/base/vite.config.ts.ejs +0 -89
  192. package/templates/vue/base/src/main.ts.ejs +0 -61
  193. package/templates/vue/micro-frontends/qiankun/base/vite.config.ts.ejs +0 -89
@@ -0,0 +1,22 @@
1
+ /**
2
+ * 模板渲染核心模块
3
+ * 处理模板文件的复制和合并逻辑
4
+ */
5
+ /**
6
+ * 渲染模板到目标目录
7
+ * 支持物理路径合并和配置文件深度合并
8
+ * @param src 源路径
9
+ * @param dest 目标路径
10
+ * @throws {Error} 如果路径不安全、文件操作失败
11
+ */
12
+ export declare function renderTemplate(src: string, dest: string): void;
13
+ /**
14
+ * 更新 package.json 的元数据字段(name, description, author, packageManager)
15
+ * @param packageJsonPath package.json 文件路径
16
+ * @param projectName 项目名称
17
+ * @param description 项目描述
18
+ * @param author 作者
19
+ * @param packageManager 包管理器类型
20
+ * @throws {Error} 如果文件读取失败、JSON 解析失败或写入失败
21
+ */
22
+ export declare function updatePackageJsonMetadata(packageJsonPath: string, projectName: string, description: string, author: string, packageManager: string): void;
@@ -0,0 +1,177 @@
1
+ /**
2
+ * 模板渲染核心模块
3
+ * 处理模板文件的复制和合并逻辑
4
+ */
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { FILE_CONSTANTS } from "../constants/index.js";
8
+ import { deepMerge } from "../utils/deepMerge.js";
9
+ import { validatePath } from "../utils/file.js";
10
+ import { sortDependencies } from "../utils/sortDependencies.js";
11
+ /**
12
+ * 渲染模板到目标目录
13
+ * 支持物理路径合并和配置文件深度合并
14
+ * @param src 源路径
15
+ * @param dest 目标路径
16
+ * @throws {Error} 如果路径不安全、文件操作失败
17
+ */
18
+ export function renderTemplate(src, dest) {
19
+ // 验证路径安全性
20
+ validatePath(src);
21
+ validatePath(dest);
22
+ try {
23
+ const stats = fs.statSync(src);
24
+ // 处理目录
25
+ if (stats.isDirectory()) {
26
+ // 跳过 node_modules 目录
27
+ if (path.basename(src) === FILE_CONSTANTS.NODE_MODULES) {
28
+ return;
29
+ }
30
+ // 统一使用绝对路径,确保目录创建和文件复制使用相同的路径格式
31
+ const resolvedDest = path.resolve(dest);
32
+ fs.mkdirSync(resolvedDest, { recursive: true });
33
+ for (const file of fs.readdirSync(src)) {
34
+ // 验证文件名安全性
35
+ if (file.includes('..') || file.includes('~')) {
36
+ throw new Error(`不安全的文件名: ${file}`);
37
+ }
38
+ renderTemplate(path.resolve(src, file), path.resolve(resolvedDest, file));
39
+ }
40
+ return;
41
+ }
42
+ // 处理文件
43
+ const filename = path.basename(src);
44
+ // 跳过 .ejs 文件(不再使用)
45
+ if (filename.endsWith(FILE_CONSTANTS.EJS_EXTENSION)) {
46
+ return;
47
+ }
48
+ // 处理 package.json - 深度合并
49
+ if (filename === FILE_CONSTANTS.PACKAGE_JSON) {
50
+ renderPackageJson(src, dest);
51
+ return;
52
+ }
53
+ // 跳过 pnpm-workspace.yaml(不再使用)
54
+ if (filename === FILE_CONSTANTS.PNPM_WORKSPACE_YAML) {
55
+ return;
56
+ }
57
+ // 处理特殊文件名转换(如 _gitignore -> .gitignore)
58
+ const targetFilename = renameFile(filename);
59
+ const targetPath = path.resolve(path.dirname(dest), targetFilename);
60
+ // 确保目标文件的父目录存在
61
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
62
+ // 普通文件直接复制(后面的会覆盖前面的)
63
+ fs.copyFileSync(src, targetPath);
64
+ }
65
+ catch (error) {
66
+ const errorMessage = error instanceof Error ? error.message : String(error);
67
+ throw new Error(`渲染模板失败: ${src} -> ${dest}\n错误: ${errorMessage}`, {
68
+ cause: error,
69
+ });
70
+ }
71
+ }
72
+ /**
73
+ * 对 package.json 的依赖进行排序
74
+ * @param packageJson package.json 对象(会被修改)
75
+ */
76
+ function sortPackageJsonDependencies(packageJson) {
77
+ if (packageJson.dependencies) {
78
+ packageJson.dependencies = sortDependencies(packageJson.dependencies);
79
+ }
80
+ if (packageJson.devDependencies) {
81
+ packageJson.devDependencies = sortDependencies(packageJson.devDependencies);
82
+ }
83
+ }
84
+ /**
85
+ * 渲染 package.json - 深度合并
86
+ * @param src 源文件路径
87
+ * @param dest 目标文件路径
88
+ * @throws {Error} 如果文件读取失败、JSON 解析失败或写入失败
89
+ */
90
+ function renderPackageJson(src, dest) {
91
+ try {
92
+ const srcContent = fs.readFileSync(src, 'utf-8');
93
+ const newPackage = JSON.parse(srcContent);
94
+ if (fs.existsSync(dest)) {
95
+ const destContent = fs.readFileSync(dest, 'utf-8');
96
+ const existingPackage = JSON.parse(destContent);
97
+ const merged = deepMerge(existingPackage, newPackage);
98
+ sortPackageJsonDependencies(merged);
99
+ fs.writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\n`);
100
+ }
101
+ else {
102
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
103
+ fs.writeFileSync(dest, `${JSON.stringify(newPackage, null, 2)}\n`);
104
+ }
105
+ }
106
+ catch (error) {
107
+ const errorMessage = error instanceof Error ? error.message : String(error);
108
+ if (error instanceof SyntaxError) {
109
+ throw new TypeError(`package.json 解析失败: ${src}\n错误: ${errorMessage}`, { cause: error });
110
+ }
111
+ throw new Error(`处理 package.json 失败: ${src} -> ${dest}\n错误: ${errorMessage}`, { cause: error });
112
+ }
113
+ }
114
+ /**
115
+ * 获取包管理器的默认版本号
116
+ * @param packageManager 包管理器类型
117
+ * @returns 包管理器版本字符串,如果未找到则返回 pnpm 的默认版本
118
+ */
119
+ function getPackageManagerVersion(packageManager) {
120
+ const versions = {
121
+ pnpm: '10.8.0',
122
+ npm: '10.9.0',
123
+ yarn: '4.1.0',
124
+ };
125
+ return versions[packageManager] || versions.pnpm;
126
+ }
127
+ /**
128
+ * 更新 package.json 的元数据字段(name, description, author, packageManager)
129
+ * @param packageJsonPath package.json 文件路径
130
+ * @param projectName 项目名称
131
+ * @param description 项目描述
132
+ * @param author 作者
133
+ * @param packageManager 包管理器类型
134
+ * @throws {Error} 如果文件读取失败、JSON 解析失败或写入失败
135
+ */
136
+ export function updatePackageJsonMetadata(packageJsonPath, projectName, description, author, packageManager) {
137
+ if (!fs.existsSync(packageJsonPath)) {
138
+ return;
139
+ }
140
+ try {
141
+ const content = fs.readFileSync(packageJsonPath, 'utf-8');
142
+ const packageJson = JSON.parse(content);
143
+ // 更新元数据字段
144
+ packageJson.name = projectName;
145
+ if (description) {
146
+ packageJson.description = description;
147
+ }
148
+ if (author) {
149
+ packageJson.author = author;
150
+ }
151
+ // 更新 packageManager 字段
152
+ packageJson.packageManager = `${packageManager}@${getPackageManagerVersion(packageManager)}`;
153
+ // 排序依赖
154
+ sortPackageJsonDependencies(packageJson);
155
+ fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
156
+ }
157
+ catch (error) {
158
+ const errorMessage = error instanceof Error ? error.message : String(error);
159
+ if (error instanceof SyntaxError) {
160
+ throw new TypeError(`package.json 解析失败: ${packageJsonPath}\n错误: ${errorMessage}`, { cause: error });
161
+ }
162
+ throw new Error(`更新 package.json 元数据失败: ${packageJsonPath}\n错误: ${errorMessage}`, { cause: error });
163
+ }
164
+ }
165
+ /**
166
+ * 重命名特殊文件
167
+ * 某些文件不能以 . 开头存在于模板中,需要特殊处理
168
+ * @param name 原始文件名
169
+ * @returns 转换后的文件名,_ 开头的文件会转换为 . 开头
170
+ */
171
+ function renameFile(name) {
172
+ // _开头的文件转换为.开头
173
+ if (name.startsWith('_')) {
174
+ return `.${name.slice(1)}`;
175
+ }
176
+ return name;
177
+ }
@@ -2,5 +2,3 @@
2
2
  * 生成器导出
3
3
  */
4
4
  export * from './project.ts';
5
- export * from './react.ts';
6
- export * from './vue.ts';
@@ -2,5 +2,3 @@
2
2
  * 生成器导出
3
3
  */
4
4
  export * from "./project.js";
5
- export * from "./react.js";
6
- export * from "./vue.js";
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * 项目生成器
3
3
  * 根据配置生成完整的项目结构
4
+ * 支持三层嵌套优先级 (L1: common, L2: framework, L3: micro-frontend)
4
5
  */
5
6
  import type { ProjectConfigType } from '../types/index.ts';
6
7
  /**
@@ -1,10 +1,57 @@
1
1
  /**
2
2
  * 项目生成器
3
3
  * 根据配置生成完整的项目结构
4
+ * 支持三层嵌套优先级 (L1: common, L2: framework, L3: micro-frontend)
4
5
  */
5
- import { emptyDir } from "../utils/file.js";
6
- import { generateReactProject } from "./react.js";
7
- import { generateVueProject } from "./vue.js";
6
+ import path from 'node:path';
7
+ import { FILE_CONSTANTS } from "../constants/index.js";
8
+ import { renderCommonFeatures, renderFrameworkFeatures, renderMicroFrontendFeatures, } from "../core/feature.js";
9
+ import { renderTemplate, updatePackageJsonMetadata } from "../core/template.js";
10
+ import { emptyDir, getTemplatesDir } from "../utils/file.js";
11
+ // ============================================================================
12
+ // 内部函数
13
+ // ============================================================================
14
+ /**
15
+ * 渲染所有基础模板
16
+ * 按三层嵌套优先级渲染: L1 (common) -> L2 (framework) -> L3 (micro-frontend)
17
+ * @param templatesDir 模板根目录
18
+ * @param framework 框架类型
19
+ * @param microFrontend 是否启用微前端
20
+ * @param microFrontendEngine 微前端引擎类型
21
+ * @param targetDir 目标目录
22
+ * @throws {Error} 如果模板渲染失败
23
+ */
24
+ function renderBaseTemplates(templatesDir, framework, microFrontend, microFrontendEngine, targetDir) {
25
+ // 1. 渲染 L1: 公共基础模板(通用层)
26
+ renderTemplate(path.join(templatesDir, 'common', 'base'), targetDir);
27
+ // 2. 渲染 L2: 框架基础模板(框架标准层)
28
+ renderTemplate(path.join(templatesDir, framework, 'base'), targetDir);
29
+ // 3. 渲染 L3: 微前端基础模板(架构增强层)- 按需覆盖
30
+ if (microFrontend && microFrontendEngine) {
31
+ const microFrontendPath = path.join(templatesDir, framework, 'micro-frontends', microFrontendEngine, 'base');
32
+ renderTemplate(microFrontendPath, targetDir);
33
+ }
34
+ }
35
+ /**
36
+ * 渲染所有 feature 模板
37
+ * 按三层嵌套优先级渲染: common features -> framework features -> micro-frontend features
38
+ * @param config 项目配置
39
+ * @param targetDir 目标目录
40
+ * @throws {Error} 如果 feature 渲染失败
41
+ */
42
+ function renderAllFeatures(config, targetDir) {
43
+ // 1. 渲染公共 feature 模板
44
+ renderCommonFeatures(config, targetDir);
45
+ // 2. 渲染框架 feature 模板
46
+ renderFrameworkFeatures(config, targetDir);
47
+ // 3. 渲染微前端专属 features(覆盖标准 features)
48
+ if (config.microFrontend && config.microFrontendEngine) {
49
+ renderMicroFrontendFeatures(config, targetDir, config.microFrontendEngine);
50
+ }
51
+ }
52
+ // ============================================================================
53
+ // 公共 API
54
+ // ============================================================================
8
55
  /**
9
56
  * 生成项目
10
57
  * @param config 项目配置
@@ -12,16 +59,22 @@ import { generateVueProject } from "./vue.js";
12
59
  * @throws {Error} 如果框架不支持或项目生成失败
13
60
  */
14
61
  export async function generateProject(config) {
15
- // 清空并创建项目根目录(确保干净的构建环境)
16
- emptyDir(config.targetDir);
17
- // 根据框架类型生成不同的项目结构
18
- if (config.framework === 'vue') {
19
- await generateVueProject(config);
20
- }
21
- else if (config.framework === 'react') {
22
- await generateReactProject(config);
23
- }
24
- else {
62
+ // 支持的框架列表
63
+ // TODO: React 功能暂时关闭
64
+ // const supportedFrameworks = ['vue', 'react']
65
+ const supportedFrameworks = ['vue'];
66
+ if (!supportedFrameworks.includes(config.framework)) {
25
67
  throw new Error(`不支持的框架: ${config.framework}`);
26
68
  }
69
+ const { targetDir, framework, microFrontend, microFrontendEngine } = config;
70
+ const templatesDir = getTemplatesDir();
71
+ // 清空并创建项目根目录(确保干净的构建环境)
72
+ emptyDir(targetDir);
73
+ // 1. 渲染所有基础模板
74
+ renderBaseTemplates(templatesDir, framework, microFrontend, microFrontendEngine, targetDir);
75
+ // 2. 渲染所有 feature 模板
76
+ renderAllFeatures(config, targetDir);
77
+ // 3. 更新 package.json 元数据字段
78
+ const packageJsonPath = path.join(targetDir, FILE_CONSTANTS.PACKAGE_JSON);
79
+ updatePackageJsonMetadata(packageJsonPath, config.projectName, config.description, config.author, config.packageManager);
27
80
  }
@@ -1,12 +1,12 @@
1
1
  /**
2
- * React 项目生成器
3
- * 采用物理路径合并 + EJS 模板 + 数据驱动配置
2
+ * React project generator
3
+ * Uses physical path merging + fixed TypeScript templates + data-driven configuration
4
4
  */
5
5
  import type { ProjectConfigType } from '../types/index.ts';
6
6
  /**
7
- * 生成 React 项目
8
- * @param config 项目配置
7
+ * Generate React project
8
+ * @param config - Project configuration
9
9
  * @returns Promise<void>
10
- * @throws {Error} 如果项目生成失败
10
+ * @throws {Error} If project generation fails
11
11
  */
12
12
  export declare function generateReactProject(config: ProjectConfigType): Promise<void>;
@@ -1,17 +1,14 @@
1
1
  /**
2
- * React 项目生成器
3
- * 采用物理路径合并 + EJS 模板 + 数据驱动配置
2
+ * React project generator
3
+ * Uses physical path merging + fixed TypeScript templates + data-driven configuration
4
4
  */
5
5
  import { generateFrameworkProject } from "../utils/index.js";
6
6
  /**
7
- * 生成 React 项目
8
- * @param config 项目配置
7
+ * Generate React project
8
+ * @param config - Project configuration
9
9
  * @returns Promise<void>
10
- * @throws {Error} 如果项目生成失败
10
+ * @throws {Error} If project generation fails
11
11
  */
12
12
  export async function generateReactProject(config) {
13
- generateFrameworkProject(config, {
14
- mainTemplate: 'src/main.tsx.ejs',
15
- mainOutput: 'src/main.tsx',
16
- });
13
+ generateFrameworkProject(config);
17
14
  }
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Vue 项目生成器
3
- * 采用物理路径合并 + EJS 模板 + 数据驱动配置
2
+ * Vue project generator
3
+ * Uses physical path merging + fixed TypeScript templates + data-driven configuration
4
4
  */
5
5
  import type { ProjectConfigType } from '../types/index.ts';
6
6
  /**
7
- * 生成 Vue 项目
8
- * @param config 项目配置
7
+ * Generate Vue project
8
+ * @param config - Project configuration
9
9
  * @returns Promise<void>
10
- * @throws {Error} 如果项目生成失败
10
+ * @throws {Error} If project generation fails
11
11
  */
12
12
  export declare function generateVueProject(config: ProjectConfigType): Promise<void>;
@@ -1,17 +1,14 @@
1
1
  /**
2
- * Vue 项目生成器
3
- * 采用物理路径合并 + EJS 模板 + 数据驱动配置
2
+ * Vue project generator
3
+ * Uses physical path merging + fixed TypeScript templates + data-driven configuration
4
4
  */
5
5
  import { generateFrameworkProject } from "../utils/index.js";
6
6
  /**
7
- * 生成 Vue 项目
8
- * @param config 项目配置
7
+ * Generate Vue project
8
+ * @param config - Project configuration
9
9
  * @returns Promise<void>
10
- * @throws {Error} 如果项目生成失败
10
+ * @throws {Error} If project generation fails
11
11
  */
12
12
  export async function generateVueProject(config) {
13
- generateFrameworkProject(config, {
14
- mainTemplate: 'src/main.ts.ejs',
15
- mainOutput: 'src/main.ts',
16
- });
13
+ generateFrameworkProject(config);
17
14
  }
package/dist/test.d.ts CHANGED
@@ -1,9 +1,5 @@
1
1
  /**
2
2
  * 测试脚本
3
3
  * 通过文件系统扫描自动生成所有测试用例组合
4
- *
5
- * 用法:
6
- * pnpm test # 生成所有测试用例
7
- * pnpm test --minimal # 只生成全量和最小配置
8
4
  */
9
5
  export {};
package/dist/test.js CHANGED
@@ -1,10 +1,6 @@
1
1
  /**
2
2
  * 测试脚本
3
3
  * 通过文件系统扫描自动生成所有测试用例组合
4
- *
5
- * 用法:
6
- * pnpm test # 生成所有测试用例
7
- * pnpm test --minimal # 只生成全量和最小配置
8
4
  */
9
5
  import path from 'node:path';
10
6
  import process from 'node:process';
@@ -12,9 +8,8 @@ import { fileURLToPath } from 'node:url';
12
8
  import chalk from 'chalk';
13
9
  import fs from 'fs-extra';
14
10
  import { FILE_CONSTANTS } from "./constants/index.js";
11
+ import { featureToConfig, getRouteModeFeatures, scanAllFeatures } from "./core/feature.js";
15
12
  import { generateProject } from "./generators/index.js";
16
- import { featureToConfig, scanAllFeatures } from "./utils/featureMapping.js";
17
- import { getRouteModeFeatures } from "./utils/routeModeMapping.js";
18
13
  const __filename = fileURLToPath(import.meta.url);
19
14
  const __dirname = path.dirname(__filename);
20
15
  /** 测试输出目录 */
@@ -24,6 +19,8 @@ const TEST_OUTPUT_DIR = path.resolve(__dirname, '../test');
24
19
  * 集中管理测试选项,方便随时调整
25
20
  */
26
21
  const TEST_CONFIG = {
22
+ /** 是否使用 minimal 模式(只生成全量和最小配置) */
23
+ minimal: false,
27
24
  /** 固定默认值(不参与组合测试) */
28
25
  defaults: {
29
26
  /** 项目名称(会自动生成,此处为描述) */
@@ -44,11 +41,17 @@ const TEST_CONFIG = {
44
41
  /** 参与组合测试的选项 */
45
42
  combinations: {
46
43
  /** 框架列表(空数组表示不启用) */
47
- frameworks: ['vue', 'react'],
44
+ // TODO: React 功能暂时关闭
45
+ // frameworks: ['vue', 'react'] as FrameworkType[],
46
+ frameworks: ['vue'],
48
47
  /** UI 库配置(按框架分组,空数组表示不启用,需要明确配置才启用) */
49
48
  uiLibraries: {
50
- vue: ['element-plus', 'ant-design-vue'], // Vue 可用的 UI 库
51
- react: ['ant-design'], // React 可用的 UI 库
49
+ // TODO: Ant Design Vue 功能暂时关闭
50
+ // vue: ['element-plus', 'ant-design-vue'] as string[], // Vue 可用的 UI 库
51
+ vue: ['element-plus'], // Vue 框架可用的 UI 库
52
+ // TODO: React 功能暂时关闭
53
+ // react: ['ant-design'] as string[], // React 可用的 UI 库
54
+ react: [], // React 功能暂时关闭
52
55
  },
53
56
  /** 路由模式列表(空数组表示不启用) */
54
57
  routeModes: ['manualRoutes', 'pageRoutes'],
@@ -155,7 +158,7 @@ function generateTestConfigs() {
155
158
  // 路由模式列表(空数组表示不启用,使用默认值)
156
159
  const routeModesToTest = TEST_CONFIG.combinations.routeModes.length > 0
157
160
  ? routeModes.filter(routeMode => TEST_CONFIG.combinations.routeModes.includes(routeMode))
158
- : (routeModes.length > 0 ? routeModes : ['manualRoutes']); // 默认
161
+ : (routeModes.length > 0 ? routeModes : ['manualRoutes']); // 默认路由模式
159
162
  if (routeModesToTest.length === 0) {
160
163
  continue;
161
164
  }
@@ -165,10 +168,10 @@ function generateTestConfigs() {
165
168
  // 如果配置了微前端引擎,生成两种组合:不带微前端(null)和带微前端(配置的引擎)
166
169
  // 如果没配置,只生成不带微前端的组合
167
170
  const microFrontendOptions = microFrontendEnginesToTest.length > 0
168
- ? [null, ...microFrontendEnginesToTest] // 总是包含 null(不带),再加上配置的引擎
169
- : [null]; // 如果没配置,只生成不带微前端的
171
+ ? [null, ...microFrontendEnginesToTest] // 总是包含 null(不带微前端),再加上配置的引擎
172
+ : [null]; // 如果没配置微前端引擎,只生成不带微前端的组合
170
173
  for (const microFrontendEngine of microFrontendOptions) {
171
- // 生成所有布尔 features 的组合(2^n 种)
174
+ // 生成所有布尔特性的组合(2^n 种)
172
175
  const combinations = generateAllCombinations(filteredBooleanFeatures);
173
176
  // 包管理器列表(空数组表示不启用)
174
177
  const packageManagersToTest = TEST_CONFIG.combinations.packageManagers;
@@ -176,7 +179,16 @@ function generateTestConfigs() {
176
179
  continue;
177
180
  }
178
181
  for (const packageManager of packageManagersToTest) {
179
- for (const combination of combinations) {
182
+ // 如果启用 minimal 模式,只生成全开和全关两种组合
183
+ const combinationsToTest = TEST_CONFIG.minimal && filteredBooleanFeatures.length > 0
184
+ ? [
185
+ // 全关(minimal)
186
+ Array.from({ length: filteredBooleanFeatures.length }).fill(false),
187
+ // 全开(full)
188
+ Array.from({ length: filteredBooleanFeatures.length }).fill(true),
189
+ ]
190
+ : combinations;
191
+ for (const combination of combinationsToTest) {
180
192
  const config = {
181
193
  framework,
182
194
  uiLibrary: uiLibrary,
@@ -185,11 +197,11 @@ function generateTestConfigs() {
185
197
  microFrontend: microFrontendEngine !== null,
186
198
  microFrontendEngine: microFrontendEngine || undefined,
187
199
  };
188
- // 根据 routeMode 设置对应的布尔 feature
200
+ // 根据路由模式设置对应的布尔特性
189
201
  const routeModeFeatures = getRouteModeFeatures(routeModeFeature);
190
202
  config.manualRoutes = routeModeFeatures.manualRoutes;
191
203
  config.pageRoutes = routeModeFeatures.pageRoutes;
192
- // 应用布尔 features 的组合
204
+ // 应用布尔特性的组合
193
205
  for (let i = 0; i < filteredBooleanFeatures.length; i++) {
194
206
  const feature = filteredBooleanFeatures[i];
195
207
  const enabled = combination[i];
@@ -280,7 +292,7 @@ async function generateTestProjects() {
280
292
  framework: config.framework,
281
293
  uiLibrary: config.uiLibrary,
282
294
  routeMode: config.routeMode,
283
- // feature 名称与目录名称一致
295
+ // 特性名称与目录名称一致
284
296
  pinia: config.framework === 'vue',
285
297
  zustand: config.framework === 'react',
286
298
  ...getRouteModeFeatures(config.routeMode),
@@ -488,6 +500,9 @@ async function main() {
488
500
  console.log(chalk.blue.bold(`\n${'='.repeat(60)}`));
489
501
  console.log(chalk.blue.bold(' Vite CLI Next - 产物审计测试'));
490
502
  console.log(chalk.blue.bold('='.repeat(60)));
503
+ if (TEST_CONFIG.minimal) {
504
+ console.log(chalk.yellow(' ⚠️ 运行在 minimal 模式(只生成全量和最小配置)\n'));
505
+ }
491
506
  // 1. 生成测试项目
492
507
  await generateTestProjects();
493
508
  // 2. 审计 @moluoxixi 依赖
@@ -1,64 +1,63 @@
1
1
  /**
2
- * CLI 类型定义
3
- * 定义项目配置、模板层级等核心类型
2
+ * CLI type definitions
3
+ * Define project configuration, template layers and other core types
4
4
  */
5
5
  import type { MicroFrontendEngine } from './features.ts';
6
- export * from './ejs.ts';
7
6
  export * from './features.ts';
8
7
  /**
9
- * 框架类型
8
+ * Framework type
10
9
  */
11
10
  export type FrameworkType = 'vue' | 'react';
12
11
  /**
13
- * UI 库类型
12
+ * UI library type
14
13
  */
15
14
  export type UILibraryType = 'element-plus' | 'ant-design-vue' | 'ant-design';
16
15
  /**
17
- * 路由模式类型
16
+ * Route mode type
18
17
  */
19
18
  export type RouteModeType = 'manualRoutes' | 'pageRoutes';
20
19
  /**
21
- * 包管理器类型
20
+ * Package manager type
22
21
  */
23
22
  export type PackageManagerType = 'pnpm' | 'npm' | 'yarn';
24
23
  /**
25
- * 项目配置接口
24
+ * Project configuration interface
26
25
  */
27
26
  export interface ProjectConfigType {
28
- /** 项目名称 */
27
+ /** Project name */
29
28
  projectName: string;
30
- /** 项目描述 */
29
+ /** Project description */
31
30
  description: string;
32
- /** 作者 */
31
+ /** Author */
33
32
  author: string;
34
- /** 框架类型 */
33
+ /** Framework type */
35
34
  framework: FrameworkType;
36
- /** UI 库(feature 名称:element-plus | ant-design-vue | ant-design */
35
+ /** UI library (feature name: element-plus | ant-design-vue | ant-design) */
37
36
  uiLibrary: UILibraryType;
38
- /** 路由模式(决定使用 manualRoutes 还是 pageRoutes feature */
37
+ /** Route mode (determines manualRoutes or pageRoutes feature) */
39
38
  routeMode: RouteModeType;
40
- /** 是否启用 pinia/zustand feature */
39
+ /** Enable pinia feature (Vue) */
41
40
  pinia?: boolean;
42
- /** 是否启用 zustand feature (React) */
41
+ /** Enable zustand feature (React) */
43
42
  zustand?: boolean;
44
- /** 是否启用 manualRoutes feature */
43
+ /** Enable manualRoutes feature */
45
44
  manualRoutes?: boolean;
46
- /** 是否启用 pageRoutes feature */
45
+ /** Enable pageRoutes feature */
47
46
  pageRoutes?: boolean;
48
- /** 是否启用 i18n feature */
47
+ /** Enable i18n feature */
49
48
  i18n: boolean;
50
- /** 是否启用微前端支持 */
49
+ /** Enable micro-frontend support */
51
50
  microFrontend: boolean;
52
- /** 微前端引擎(qiankunmicro-app 等)- microFrontend true 时有效 */
51
+ /** Micro-frontend engine (qiankun, micro-app, etc.) - valid when microFrontend is true */
53
52
  microFrontendEngine?: MicroFrontendEngine;
54
- /** 是否启用 sentry feature */
53
+ /** Enable sentry feature */
55
54
  sentry: boolean;
56
- /** 是否启用 eslint feature */
55
+ /** Enable eslint feature */
57
56
  eslint: boolean;
58
- /** 是否启用 husky feature (Git Hooks) */
57
+ /** Enable husky feature (Git Hooks) */
59
58
  husky: boolean;
60
- /** 包管理器 */
59
+ /** Package manager */
61
60
  packageManager: PackageManagerType;
62
- /** 目标目录 */
61
+ /** Target directory */
63
62
  targetDir: string;
64
63
  }
@@ -1,6 +1,5 @@
1
1
  /**
2
- * CLI 类型定义
3
- * 定义项目配置、模板层级等核心类型
2
+ * CLI type definitions
3
+ * Define project configuration, template layers and other core types
4
4
  */
5
- export * from "./ejs.js";
6
5
  export * from "./features.js";