@moluoxixi/create-app 2.0.443 → 2.0.444

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 (187) hide show
  1. package/README.md +0 -2
  2. package/dist/commands/create.js +0 -1
  3. package/dist/core/projectAtom.d.ts +43 -0
  4. package/dist/core/projectAtom.js +146 -0
  5. package/dist/core/projectOutput.d.ts +11 -0
  6. package/dist/core/projectOutput.js +402 -0
  7. package/dist/core/template.js +5 -0
  8. package/dist/generators/project.js +4 -1
  9. package/dist/types/features.d.ts +0 -2
  10. package/dist/types/features.js +0 -2
  11. package/package.json +2 -1
  12. package/templates/common/base/node_modules/.bin/autoprefixer +2 -2
  13. package/templates/common/base/node_modules/.bin/browserslist +4 -4
  14. package/templates/common/base/node_modules/.bin/jiti +4 -4
  15. package/templates/common/base/node_modules/.bin/sass +2 -2
  16. package/templates/common/base/node_modules/.bin/uuid +2 -2
  17. package/templates/common/base/node_modules/.bin/vite +2 -2
  18. package/templates/common/base/node_modules/.bin/yaml +4 -4
  19. package/templates/common/base/package.json +2 -4
  20. package/templates/common/features/eslint/node_modules/.bin/browserslist +4 -4
  21. package/templates/common/features/eslint/node_modules/.bin/eslint +2 -2
  22. package/templates/common/features/eslint/node_modules/.bin/jiti +4 -4
  23. package/templates/common/features/eslint/node_modules/.bin/sass +4 -4
  24. package/templates/common/features/eslint/node_modules/.bin/vite +17 -0
  25. package/templates/common/features/eslint/node_modules/.bin/vitest +4 -4
  26. package/templates/common/features/eslint/node_modules/.bin/yaml +4 -4
  27. package/templates/common/features/husky/node_modules/.bin/commitizen +2 -2
  28. package/templates/common/features/husky/node_modules/.bin/commitlint +2 -2
  29. package/templates/common/features/husky/node_modules/.bin/cz +2 -2
  30. package/templates/common/features/husky/node_modules/.bin/cz-cust +2 -2
  31. package/templates/common/features/husky/node_modules/.bin/cz-customizable +2 -2
  32. package/templates/common/features/husky/node_modules/.bin/git-cz +2 -2
  33. package/templates/react/base/env.d.ts +1 -0
  34. package/templates/react/base/node_modules/.bin/jiti +4 -4
  35. package/templates/react/base/node_modules/.bin/sass +4 -4
  36. package/templates/react/base/node_modules/.bin/vite +4 -4
  37. package/templates/react/base/node_modules/.bin/yaml +4 -4
  38. package/templates/react/features/manualRoutes/tsconfig.base.json +0 -1
  39. package/templates/react/features/pageRoutes/node_modules/.bin/jiti +4 -4
  40. package/templates/react/features/pageRoutes/node_modules/.bin/sass +4 -4
  41. package/templates/react/features/pageRoutes/node_modules/.bin/vite +4 -4
  42. package/templates/react/features/pageRoutes/node_modules/.bin/yaml +4 -4
  43. package/templates/react/features/pageRoutes/package.json +0 -1
  44. package/templates/react/features/pageRoutes/tsconfig.base.json +0 -1
  45. package/templates/react/features/sentry/package.json +1 -3
  46. package/templates/react/features/zustand/tsconfig.base.json +0 -1
  47. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/jiti +4 -4
  48. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/sass +4 -4
  49. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/vite +2 -2
  50. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/yaml +4 -4
  51. package/templates/react/micro-frontends/qiankun/base/package.json +1 -2
  52. package/templates/react/micro-frontends/qiankun/base/tsconfig.base.json +0 -1
  53. package/templates/vue/base/atom.mjs +26 -0
  54. package/templates/vue/base/env.d.ts +1 -0
  55. package/templates/vue/base/node_modules/.bin/jiti +17 -0
  56. package/templates/{react/features/sentry → vue/base}/node_modules/.bin/sass +4 -4
  57. package/templates/vue/{features/sentry → base}/node_modules/.bin/tsx +2 -2
  58. package/templates/vue/base/node_modules/.bin/vite +17 -0
  59. package/templates/vue/base/node_modules/.bin/vue-tsc +2 -2
  60. package/templates/vue/{features/sentry → base}/node_modules/.bin/yaml +4 -4
  61. package/templates/vue/base/package.json +1 -0
  62. package/templates/vue/base/src/types/index.ts +16 -0
  63. package/templates/vue/features/element-plus/atom.mjs +35 -0
  64. package/templates/vue/features/element-plus/node_modules/.bin/parser +4 -4
  65. package/templates/vue/features/element-plus/package.json +3 -2
  66. package/templates/vue/features/element-plus/src/components/SubMenu/src/index.vue +1 -1
  67. package/templates/vue/features/i18n/atom.mjs +11 -0
  68. package/templates/vue/features/pageRoutes/atom.mjs +15 -0
  69. package/templates/vue/features/pageRoutes/node_modules/.bin/jiti +4 -4
  70. package/templates/vue/features/pageRoutes/node_modules/.bin/sass +4 -4
  71. package/templates/vue/features/pageRoutes/node_modules/.bin/vite +4 -4
  72. package/templates/vue/features/pageRoutes/node_modules/.bin/yaml +4 -4
  73. package/templates/vue/features/pageRoutes/package.json +0 -1
  74. package/templates/vue/features/pinia/atom.mjs +11 -0
  75. package/templates/vue/features/sentry/atom.mjs +35 -0
  76. package/templates/vue/features/sentry/package.json +1 -3
  77. package/templates/vue/micro-frontends/qiankun/base/atom.mjs +19 -0
  78. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/jiti +4 -4
  79. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/sass +4 -4
  80. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/vite +2 -2
  81. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/yaml +4 -4
  82. package/templates/vue/micro-frontends/qiankun/base/package.json +0 -2
  83. package/templates/vue/micro-frontends/qiankun/base/src/types/index.ts +16 -0
  84. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/jiti +4 -4
  85. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/parser +4 -4
  86. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/sass +4 -4
  87. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/vite +4 -4
  88. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/yaml +4 -4
  89. package/templates/vue/micro-frontends/qiankun/features/element-plus/package.json +3 -2
  90. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/components/SubMenu/src/index.vue +1 -1
  91. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/jiti +4 -4
  92. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/sass +4 -4
  93. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/vite +4 -4
  94. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/yaml +4 -4
  95. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/jiti +4 -4
  96. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/sass +4 -4
  97. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/vite +4 -4
  98. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/yaml +4 -4
  99. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/package.json +0 -1
  100. package/templates/common/base/node_modules/.bin/parser +0 -17
  101. package/templates/common/base/node_modules/.bin/rollup +0 -17
  102. package/templates/common/base/node_modules/.bin/terser +0 -17
  103. package/templates/common/base/vite/index.ts +0 -54
  104. package/templates/common/base/vite.config.ts +0 -58
  105. package/templates/common/features/eslint/node_modules/.bin/terser +0 -17
  106. package/templates/react/base/node_modules/.bin/terser +0 -17
  107. package/templates/react/base/src/main/index.ts +0 -34
  108. package/templates/react/base/src/main.tsx +0 -34
  109. package/templates/react/features/ant-design/src/main/features/ant-design.ts +0 -21
  110. package/templates/react/features/i18n/src/main/features/i18n.ts +0 -19
  111. package/templates/react/features/pageRoutes/node_modules/.bin/browserslist +0 -17
  112. package/templates/react/features/pageRoutes/node_modules/.bin/parser +0 -17
  113. package/templates/react/features/pageRoutes/node_modules/.bin/rollup +0 -17
  114. package/templates/react/features/pageRoutes/node_modules/.bin/terser +0 -17
  115. package/templates/react/features/pageRoutes/node_modules/.bin/tsc +0 -17
  116. package/templates/react/features/pageRoutes/node_modules/.bin/tsserver +0 -17
  117. package/templates/react/features/pageRoutes/vite/features/pageRoutes.ts +0 -15
  118. package/templates/react/features/sentry/node_modules/.bin/browserslist +0 -17
  119. package/templates/react/features/sentry/node_modules/.bin/jiti +0 -17
  120. package/templates/react/features/sentry/node_modules/.bin/parser +0 -17
  121. package/templates/react/features/sentry/node_modules/.bin/rollup +0 -17
  122. package/templates/react/features/sentry/node_modules/.bin/terser +0 -17
  123. package/templates/react/features/sentry/node_modules/.bin/tsc +0 -17
  124. package/templates/react/features/sentry/node_modules/.bin/tsserver +0 -17
  125. package/templates/react/features/sentry/node_modules/.bin/tsx +0 -17
  126. package/templates/react/features/sentry/node_modules/.bin/vite +0 -17
  127. package/templates/react/features/sentry/node_modules/.bin/yaml +0 -17
  128. package/templates/react/features/sentry/src/main/features/sentry.ts +0 -20
  129. package/templates/react/features/sentry/vite/features/sentry.ts +0 -33
  130. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/browserslist +0 -17
  131. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/parser +0 -17
  132. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/rollup +0 -17
  133. package/templates/react/micro-frontends/qiankun/base/node_modules/.bin/terser +0 -17
  134. package/templates/react/micro-frontends/qiankun/base/src/main/index.ts +0 -34
  135. package/templates/react/micro-frontends/qiankun/base/src/main.tsx +0 -69
  136. package/templates/react/micro-frontends/qiankun/base/vite/index.ts +0 -54
  137. package/templates/vue/base/src/main/index.ts +0 -36
  138. package/templates/vue/base/src/main.ts +0 -34
  139. package/templates/vue/features/ant-design-vue/src/main/features/ant-design-vue.ts +0 -18
  140. package/templates/vue/features/element-plus/node_modules/.bin/browserslist +0 -17
  141. package/templates/vue/features/element-plus/node_modules/.bin/jiti +0 -17
  142. package/templates/vue/features/element-plus/node_modules/.bin/rollup +0 -17
  143. package/templates/vue/features/element-plus/node_modules/.bin/sass +0 -17
  144. package/templates/vue/features/element-plus/node_modules/.bin/terser +0 -17
  145. package/templates/vue/features/element-plus/node_modules/.bin/tsx +0 -17
  146. package/templates/vue/features/element-plus/node_modules/.bin/vite +0 -17
  147. package/templates/vue/features/element-plus/node_modules/.bin/yaml +0 -17
  148. package/templates/vue/features/element-plus/src/main/features/element-plus.ts +0 -23
  149. package/templates/vue/features/element-plus/vite/features/element-plus.ts +0 -30
  150. package/templates/vue/features/i18n/src/main/features/i18n.ts +0 -19
  151. package/templates/vue/features/pageRoutes/node_modules/.bin/browserslist +0 -17
  152. package/templates/vue/features/pageRoutes/node_modules/.bin/parser +0 -17
  153. package/templates/vue/features/pageRoutes/node_modules/.bin/rollup +0 -17
  154. package/templates/vue/features/pageRoutes/node_modules/.bin/terser +0 -17
  155. package/templates/vue/features/pageRoutes/vite/features/pageRoutes.ts +0 -15
  156. package/templates/vue/features/pinia/src/main/features/pinia.ts +0 -19
  157. package/templates/vue/features/sentry/node_modules/.bin/browserslist +0 -17
  158. package/templates/vue/features/sentry/node_modules/.bin/jiti +0 -17
  159. package/templates/vue/features/sentry/node_modules/.bin/parser +0 -17
  160. package/templates/vue/features/sentry/node_modules/.bin/rollup +0 -17
  161. package/templates/vue/features/sentry/node_modules/.bin/sass +0 -17
  162. package/templates/vue/features/sentry/node_modules/.bin/terser +0 -17
  163. package/templates/vue/features/sentry/node_modules/.bin/vite +0 -17
  164. package/templates/vue/features/sentry/src/main/features/sentry.ts +0 -22
  165. package/templates/vue/features/sentry/vite/features/sentry.ts +0 -33
  166. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/browserslist +0 -17
  167. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/parser +0 -17
  168. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/rollup +0 -17
  169. package/templates/vue/micro-frontends/qiankun/base/node_modules/.bin/terser +0 -17
  170. package/templates/vue/micro-frontends/qiankun/base/src/main/index.ts +0 -36
  171. package/templates/vue/micro-frontends/qiankun/base/src/main.ts +0 -70
  172. package/templates/vue/micro-frontends/qiankun/base/vite/index.ts +0 -54
  173. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/browserslist +0 -17
  174. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/rollup +0 -17
  175. package/templates/vue/micro-frontends/qiankun/features/element-plus/node_modules/.bin/terser +0 -17
  176. package/templates/vue/micro-frontends/qiankun/features/element-plus/src/main/features/element-plus.ts +0 -24
  177. package/templates/vue/micro-frontends/qiankun/features/element-plus/vite/features/element-plus.ts +0 -30
  178. package/templates/vue/micro-frontends/qiankun/features/manualRoutes/node_modules/.bin/terser +0 -17
  179. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/browserslist +0 -17
  180. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/parser +0 -17
  181. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/rollup +0 -17
  182. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/node_modules/.bin/terser +0 -17
  183. package/templates/vue/micro-frontends/qiankun/features/pageRoutes/vite/features/pageRoutes.ts +0 -15
  184. /package/templates/vue/features/element-plus/src/components/SubMenu/src/{_types → types}/index.ts +0 -0
  185. /package/templates/vue/features/element-plus/src/components/SubMenu/src/{_types → types}/props.ts +0 -0
  186. /package/templates/vue/micro-frontends/qiankun/features/element-plus/src/components/SubMenu/src/{_types → types}/index.ts +0 -0
  187. /package/templates/vue/micro-frontends/qiankun/features/element-plus/src/components/SubMenu/src/{_types → types}/props.ts +0 -0
package/README.md CHANGED
@@ -45,10 +45,8 @@ npm create @moluoxixi/app
45
45
  | 依赖包 | 用途 |
46
46
  |--------|------|
47
47
  | `@moluoxixi/eslint-config` | ESLint 统一配置 |
48
- | `@moluoxixi/vite-config` | Vite 构建配置 |
49
48
  | `@moluoxixi/ajax-package` | HTTP 请求封装 |
50
49
  | `@moluoxixi/class-names` | CSS 类名工具 |
51
- | `@moluoxixi/css-module-global-root-plugin` | CSS Module 插件 |
52
50
 
53
51
  ## 源码目录结构
54
52
 
@@ -81,7 +81,6 @@ export async function createProject(projectName) {
81
81
  // 显示特性信息
82
82
  console.log(chalk.blue('已启用的 @moluoxixi 依赖:'));
83
83
  console.log(chalk.gray(' @moluoxixi/eslint-config@latest'));
84
- console.log(chalk.gray(' @moluoxixi/vite-config@latest'));
85
84
  console.log(chalk.gray(' @moluoxixi/ajax-package@latest'));
86
85
  console.log('');
87
86
  }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 项目输出 atom 模块
3
+ * 读取模板目录中的 atom.mjs,并合并 main 与 vite.config 的生成贡献。
4
+ */
5
+ export declare const PROJECT_ATOM_FILE = "atom.mjs";
6
+ export type MainRenderMode = 'vue-standard' | 'vue-qiankun';
7
+ export interface ProjectAtomMainContribution {
8
+ mode?: MainRenderMode;
9
+ imports?: string[];
10
+ appSetup?: string[];
11
+ appUses?: string[];
12
+ afterAppUses?: string[];
13
+ setup?: string[];
14
+ afterSetup?: string[];
15
+ }
16
+ export interface ProjectAtomViteContribution {
17
+ imports?: string[];
18
+ plugins?: string[];
19
+ scssOptions?: string[];
20
+ }
21
+ export interface ProjectAtom {
22
+ id: string;
23
+ main?: ProjectAtomMainContribution;
24
+ vite?: ProjectAtomViteContribution;
25
+ }
26
+ export interface ProjectOutputComposition {
27
+ atomIds: string[];
28
+ main: Required<ProjectAtomMainContribution>;
29
+ vite: Required<ProjectAtomViteContribution>;
30
+ }
31
+ /**
32
+ * 读取多个模板目录中的 atom.mjs。
33
+ * @param templateDirs 按模板渲染顺序排列的模板目录
34
+ * @returns 解析后的 atom 列表
35
+ * @throws {TypeError} 当 atom.mjs 默认导出结构非法
36
+ */
37
+ export declare function loadProjectAtoms(templateDirs: string[]): Promise<ProjectAtom[]>;
38
+ /**
39
+ * 合并项目输出 atom。
40
+ * @param atoms 按模板渲染顺序排列的 atom 列表
41
+ * @returns 可供 main/vite 渲染器消费的组合结果
42
+ */
43
+ export declare function composeProjectOutput(atoms: ProjectAtom[]): ProjectOutputComposition;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * 项目输出 atom 模块
3
+ * 读取模板目录中的 atom.mjs,并合并 main 与 vite.config 的生成贡献。
4
+ */
5
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
6
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
7
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
8
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
9
+ });
10
+ }
11
+ return path;
12
+ };
13
+ import fs from 'fs-extra';
14
+ import path from 'node:path';
15
+ import { pathToFileURL } from 'node:url';
16
+ export const PROJECT_ATOM_FILE = 'atom.mjs';
17
+ /**
18
+ * 读取多个模板目录中的 atom.mjs。
19
+ * @param templateDirs 按模板渲染顺序排列的模板目录
20
+ * @returns 解析后的 atom 列表
21
+ * @throws {TypeError} 当 atom.mjs 默认导出结构非法
22
+ */
23
+ export async function loadProjectAtoms(templateDirs) {
24
+ const atoms = [];
25
+ for (const templateDir of templateDirs) {
26
+ const atomPath = path.join(templateDir, PROJECT_ATOM_FILE);
27
+ if (!fs.existsSync(atomPath)) {
28
+ continue;
29
+ }
30
+ const atomModule = await import(__rewriteRelativeImportExtension(pathToFileURL(atomPath).href, true));
31
+ const atom = atomModule.default;
32
+ assertProjectAtom(atom, atomPath);
33
+ atoms.push(atom);
34
+ }
35
+ return atoms;
36
+ }
37
+ /**
38
+ * 合并项目输出 atom。
39
+ * @param atoms 按模板渲染顺序排列的 atom 列表
40
+ * @returns 可供 main/vite 渲染器消费的组合结果
41
+ */
42
+ export function composeProjectOutput(atoms) {
43
+ const output = {
44
+ atomIds: [],
45
+ main: createEmptyMainContribution(),
46
+ vite: createEmptyViteContribution(),
47
+ };
48
+ const seenAtomIds = new Set();
49
+ for (const atom of atoms) {
50
+ if (seenAtomIds.has(atom.id)) {
51
+ continue;
52
+ }
53
+ seenAtomIds.add(atom.id);
54
+ output.atomIds.push(atom.id);
55
+ mergeMainContribution(output.main, atom.main);
56
+ mergeViteContribution(output.vite, atom.vite);
57
+ }
58
+ return output;
59
+ }
60
+ /**
61
+ * 创建空 main 贡献对象。
62
+ * @returns 带默认模式和空数组的 main 贡献
63
+ */
64
+ function createEmptyMainContribution() {
65
+ return {
66
+ mode: 'vue-standard',
67
+ imports: [],
68
+ appSetup: [],
69
+ appUses: [],
70
+ afterAppUses: [],
71
+ setup: [],
72
+ afterSetup: [],
73
+ };
74
+ }
75
+ /**
76
+ * 创建空 Vite 贡献对象。
77
+ * @returns 带空数组的 Vite 贡献
78
+ */
79
+ function createEmptyViteContribution() {
80
+ return {
81
+ imports: [],
82
+ plugins: [],
83
+ scssOptions: [],
84
+ };
85
+ }
86
+ /**
87
+ * 校验 atom 默认导出结构。
88
+ * @param atom atom 默认导出值
89
+ * @param atomPath atom 文件路径,用于错误定位
90
+ * @throws {TypeError} 当 atom 不是对象或缺少 id
91
+ */
92
+ function assertProjectAtom(atom, atomPath) {
93
+ if (!atom || typeof atom !== 'object') {
94
+ throw new TypeError(`atom.mjs 必须默认导出对象: ${atomPath}`);
95
+ }
96
+ if (!atom.id || typeof atom.id !== 'string') {
97
+ throw new TypeError(`atom.mjs 缺少字符串 id: ${atomPath}`);
98
+ }
99
+ }
100
+ /**
101
+ * 合并 main 贡献。
102
+ * @param target 合并目标
103
+ * @param source 当前 atom 的 main 贡献
104
+ */
105
+ function mergeMainContribution(target, source) {
106
+ if (!source) {
107
+ return;
108
+ }
109
+ if (source.mode) {
110
+ target.mode = source.mode;
111
+ }
112
+ pushUnique(target.imports, source.imports);
113
+ pushUnique(target.appSetup, source.appSetup);
114
+ pushUnique(target.appUses, source.appUses);
115
+ pushUnique(target.afterAppUses, source.afterAppUses);
116
+ pushUnique(target.setup, source.setup);
117
+ pushUnique(target.afterSetup, source.afterSetup);
118
+ }
119
+ /**
120
+ * 合并 Vite 贡献。
121
+ * @param target 合并目标
122
+ * @param source 当前 atom 的 Vite 贡献
123
+ */
124
+ function mergeViteContribution(target, source) {
125
+ if (!source) {
126
+ return;
127
+ }
128
+ pushUnique(target.imports, source.imports);
129
+ pushUnique(target.plugins, source.plugins);
130
+ pushUnique(target.scssOptions, source.scssOptions);
131
+ }
132
+ /**
133
+ * 追加去重后的字符串项,保持首次出现顺序。
134
+ * @param target 合并目标数组
135
+ * @param source 待追加数组
136
+ */
137
+ function pushUnique(target, source) {
138
+ if (!source) {
139
+ return;
140
+ }
141
+ for (const item of source) {
142
+ if (!target.includes(item)) {
143
+ target.push(item);
144
+ }
145
+ }
146
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 生成项目输出整理模块
3
+ * 在模板叠加完成后读取各模板 atom.mjs,把贡献合成为普通 Vite 项目文件。
4
+ */
5
+ import type { ProjectConfigType } from '../types/index.ts';
6
+ /**
7
+ * 完成生成项目的最终输出整理。
8
+ * @param config 项目配置
9
+ * @throws {Error} 如果最终文件写入、atom 读取或 package.json 清理失败
10
+ */
11
+ export declare function finalizeProjectOutput(config: ProjectConfigType): Promise<void>;
@@ -0,0 +1,402 @@
1
+ /**
2
+ * 生成项目输出整理模块
3
+ * 在模板叠加完成后读取各模板 atom.mjs,把贡献合成为普通 Vite 项目文件。
4
+ */
5
+ import fs from 'fs-extra';
6
+ import path from 'node:path';
7
+ import { composeProjectOutput, loadProjectAtoms, } from "./projectAtom.js";
8
+ import { getCommonFeatures, getFrameworkFeatures, } from "./feature.js";
9
+ import { getTemplatesDir } from "../utils/file.js";
10
+ const REMOVED_VITE_BLACK_BOX_DEPS = [
11
+ '@moluoxixi/vite-config',
12
+ '@moluoxixi/css-module-global-root-plugin',
13
+ 'jiti',
14
+ ];
15
+ /**
16
+ * 完成生成项目的最终输出整理。
17
+ * @param config 项目配置
18
+ * @throws {Error} 如果最终文件写入、atom 读取或 package.json 清理失败
19
+ */
20
+ export async function finalizeProjectOutput(config) {
21
+ removeRuntimeLoaderDirs(config.targetDir);
22
+ const atomDirs = collectProjectAtomDirs(config);
23
+ const atoms = await loadProjectAtoms(atomDirs);
24
+ const output = composeProjectOutput(atoms);
25
+ writeMainEntry(config, output);
26
+ writeViteConfig(config, output);
27
+ removeViteBlackBoxDependencies(config.targetDir);
28
+ }
29
+ /**
30
+ * 移除只属于脚手架组合阶段的运行时 loader 目录。
31
+ * @param targetDir 生成项目根目录
32
+ */
33
+ function removeRuntimeLoaderDirs(targetDir) {
34
+ fs.removeSync(path.join(targetDir, 'src', 'main'));
35
+ fs.removeSync(path.join(targetDir, 'vite'));
36
+ }
37
+ /**
38
+ * 收集当前项目配置启用的模板 atom 目录。
39
+ * @param config 项目配置
40
+ * @returns 按模板叠加顺序排列的目录
41
+ */
42
+ function collectProjectAtomDirs(config) {
43
+ const templatesDir = getTemplatesDir();
44
+ const atomDirs = [
45
+ path.join(templatesDir, 'common', 'base'),
46
+ path.join(templatesDir, config.framework, 'base'),
47
+ ];
48
+ atomDirs.push(...collectCommonFeatureAtomDirs(config, templatesDir));
49
+ atomDirs.push(...collectFrameworkFeatureAtomDirs(config, templatesDir));
50
+ if (config.microFrontend && config.microFrontendEngine) {
51
+ atomDirs.push(path.join(templatesDir, config.framework, 'micro-frontends', config.microFrontendEngine, 'base'));
52
+ }
53
+ atomDirs.push(...collectMicroFrontendFeatureAtomDirs(config, templatesDir));
54
+ return atomDirs;
55
+ }
56
+ /**
57
+ * 收集公共 feature 的 atom 目录。
58
+ * @param config 项目配置
59
+ * @param templatesDir 模板根目录
60
+ * @returns 启用的公共 feature 目录
61
+ */
62
+ function collectCommonFeatureAtomDirs(config, templatesDir) {
63
+ const availableFeatures = getCommonFeatures();
64
+ const featureDirs = [];
65
+ for (const [key, value] of Object.entries(config)) {
66
+ if (value === true && availableFeatures.includes(key)) {
67
+ featureDirs.push(path.join(templatesDir, 'common', 'features', key));
68
+ }
69
+ }
70
+ return featureDirs;
71
+ }
72
+ /**
73
+ * 收集框架 feature 的 atom 目录。
74
+ * @param config 项目配置
75
+ * @param templatesDir 模板根目录
76
+ * @returns 启用的框架 feature 目录
77
+ */
78
+ function collectFrameworkFeatureAtomDirs(config, templatesDir) {
79
+ const availableFeatures = getFrameworkFeatures(config.framework);
80
+ const featureDirs = [];
81
+ for (const [key, value] of Object.entries(config)) {
82
+ if (value === true && availableFeatures.includes(key)) {
83
+ featureDirs.push(path.join(templatesDir, config.framework, 'features', key));
84
+ }
85
+ }
86
+ if (config.uiLibrary && availableFeatures.includes(config.uiLibrary)) {
87
+ featureDirs.push(path.join(templatesDir, config.framework, 'features', config.uiLibrary));
88
+ }
89
+ return featureDirs;
90
+ }
91
+ /**
92
+ * 收集微前端 feature 的 atom 目录。
93
+ * @param config 项目配置
94
+ * @param templatesDir 模板根目录
95
+ * @returns 启用的微前端 feature 目录
96
+ */
97
+ function collectMicroFrontendFeatureAtomDirs(config, templatesDir) {
98
+ if (!config.microFrontend || !config.microFrontendEngine) {
99
+ return [];
100
+ }
101
+ const microFrontendFeaturesPath = path.join(templatesDir, config.framework, 'micro-frontends', config.microFrontendEngine, 'features');
102
+ if (!fs.existsSync(microFrontendFeaturesPath)) {
103
+ return [];
104
+ }
105
+ const availableFeatures = fs.readdirSync(microFrontendFeaturesPath).filter((item) => {
106
+ const itemPath = path.join(microFrontendFeaturesPath, item);
107
+ return fs.statSync(itemPath).isDirectory();
108
+ });
109
+ const featureDirs = [];
110
+ for (const [key, value] of Object.entries(config)) {
111
+ if (value === true && availableFeatures.includes(key)) {
112
+ featureDirs.push(path.join(microFrontendFeaturesPath, key));
113
+ }
114
+ }
115
+ if (config.uiLibrary && availableFeatures.includes(config.uiLibrary)) {
116
+ featureDirs.push(path.join(microFrontendFeaturesPath, config.uiLibrary));
117
+ }
118
+ return featureDirs;
119
+ }
120
+ /**
121
+ * 写入框架对应的最终入口文件。
122
+ * @param config 项目配置
123
+ * @param output atom 合并后的输出模型
124
+ * @throws {Error} 如果框架或入口模式不受支持
125
+ */
126
+ function writeMainEntry(config, output) {
127
+ if (config.framework !== 'vue') {
128
+ throw new Error(`不支持的框架: ${config.framework}`);
129
+ }
130
+ const mainEntryPath = path.join(config.targetDir, 'src', 'main.ts');
131
+ const content = createVueMainEntry(output);
132
+ fs.ensureDirSync(path.dirname(mainEntryPath));
133
+ fs.writeFileSync(mainEntryPath, content);
134
+ }
135
+ /**
136
+ * 生成 Vue 项目的最终入口文件内容。
137
+ * @param output atom 合并后的输出模型
138
+ * @returns main.ts 文件内容
139
+ * @throws {Error} 如果入口模式不受支持
140
+ */
141
+ function createVueMainEntry(output) {
142
+ if (output.main.mode === 'vue-standard') {
143
+ return createVueStandardMainEntry(output);
144
+ }
145
+ if (output.main.mode === 'vue-qiankun') {
146
+ return createVueQiankunMainEntry(output);
147
+ }
148
+ throw new Error(`不支持的 Vue 入口模式: ${output.main.mode}`);
149
+ }
150
+ /**
151
+ * 生成普通 Vue 项目的入口文件内容。
152
+ * @param output atom 合并后的输出模型
153
+ * @returns main.ts 文件内容
154
+ */
155
+ function createVueStandardMainEntry(output) {
156
+ return `${createMainImports(output, 'Vue 应用入口文件')}
157
+
158
+ /**
159
+ * 初始化并挂载 Vue 应用。
160
+ */
161
+ function bootstrap(): void {
162
+ const app = createApp(App)
163
+ const router = getRouter()
164
+
165
+ ${createVueAppSetup(output)}
166
+
167
+ app.mount('#app')
168
+ }
169
+
170
+ bootstrap()
171
+ `;
172
+ }
173
+ /**
174
+ * 生成 Vue + Qiankun 项目的入口文件内容。
175
+ * @param output atom 合并后的输出模型
176
+ * @returns main.ts 文件内容
177
+ */
178
+ function createVueQiankunMainEntry(output) {
179
+ return `${createMainImports(output, 'Vue 微前端应用入口文件')}
180
+
181
+ let app: ReturnType<typeof createApp> | null = null
182
+
183
+ /**
184
+ * 解析 Vue 应用挂载节点,避免 qiankun 容器缺失时静默失败。
185
+ * @param container qiankun 传入的容器节点
186
+ * @returns Vue 可挂载的目标节点或选择器
187
+ * @throws {Error} 当 qiankun 容器内不存在 #app 节点
188
+ */
189
+ function resolveMountTarget(container?: Element): Element | string {
190
+ if (!container) {
191
+ return '#app'
192
+ }
193
+
194
+ const target = container.querySelector('#app')
195
+ if (!target) {
196
+ throw new Error('Qiankun container missing #app mount target')
197
+ }
198
+ return target
199
+ }
200
+
201
+ /**
202
+ * 渲染 Vue 应用,独立运行和 qiankun 挂载共用同一流程。
203
+ * @param props qiankun 传入的生命周期属性
204
+ */
205
+ function render(props: Record<string, unknown> = {}): void {
206
+ const { container } = props as { container?: Element }
207
+ app = createApp(App)
208
+ const router = getRouter(props)
209
+
210
+ ${createVueAppSetup(output)}
211
+
212
+ app.mount(resolveMountTarget(container))
213
+ }
214
+
215
+ if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
216
+ render({})
217
+ }
218
+ else {
219
+ renderWithQiankun({
220
+ mount(props: Record<string, unknown>) {
221
+ render(props)
222
+ },
223
+ bootstrap() {},
224
+ unmount() {
225
+ app?.unmount()
226
+ app = null
227
+ },
228
+ update() {},
229
+ })
230
+ }
231
+ `;
232
+ }
233
+ /**
234
+ * 创建 main.ts 的 import 区块。
235
+ * @param output atom 合并后的输出模型
236
+ * @param title 入口文件标题
237
+ * @returns import 文本
238
+ */
239
+ function createMainImports(output, title) {
240
+ return [
241
+ '/**',
242
+ ` * ${title}`,
243
+ ' * 由 create-app 在生成阶段按已选能力合成。',
244
+ ' */',
245
+ '',
246
+ ...output.main.imports,
247
+ ].join('\n');
248
+ }
249
+ /**
250
+ * 创建 Vue 应用插件安装和初始化代码。
251
+ * @param output atom 合并后的输出模型
252
+ * @returns 已缩进的代码块
253
+ */
254
+ function createVueAppSetup(output) {
255
+ const lines = [
256
+ ...output.main.setup,
257
+ ...output.main.appSetup,
258
+ ...output.main.appUses,
259
+ 'app.use(router)',
260
+ ...output.main.afterSetup,
261
+ ...output.main.afterAppUses,
262
+ ];
263
+ return indentLines(lines.filter(Boolean), 2);
264
+ }
265
+ /**
266
+ * 写入最终 Vite 配置文件。
267
+ * @param config 项目配置
268
+ * @param output atom 合并后的输出模型
269
+ * @throws {Error} 如果框架不受支持
270
+ */
271
+ function writeViteConfig(config, output) {
272
+ if (config.framework !== 'vue') {
273
+ throw new Error(`不支持的框架: ${config.framework}`);
274
+ }
275
+ const viteConfigPath = path.join(config.targetDir, 'vite.config.ts');
276
+ fs.writeFileSync(viteConfigPath, createVueViteConfig(output));
277
+ }
278
+ /**
279
+ * 生成 Vue 项目的透明 Vite 配置。
280
+ * @param output atom 合并后的输出模型
281
+ * @returns vite.config.ts 文件内容
282
+ */
283
+ function createVueViteConfig(output) {
284
+ return `${createViteConfigImports(output)}
285
+
286
+ /**
287
+ * 创建 Vue 项目的 Vite 配置。
288
+ */
289
+ export default defineConfig(({ mode }) => {
290
+ const env = loadEnv(mode, process.cwd())
291
+ const appCode = env.VITE_APP_CODE || ''
292
+
293
+ const plugins: PluginOption[] = []
294
+ ${indentLines(output.vite.plugins, 2)}
295
+
296
+ return {
297
+ base: appCode ? \`/\${appCode}\` : '/',
298
+ plugins,
299
+ resolve: {
300
+ alias: {
301
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
302
+ },
303
+ },
304
+ build: {
305
+ outDir: 'dist',
306
+ },
307
+ server: {
308
+ host: '0.0.0.0',
309
+ port: Number(env.VITE_APP_PORT || 3000),
310
+ proxy: {
311
+ '/api': {
312
+ changeOrigin: true,
313
+ target: 'http://localhost:3000',
314
+ },
315
+ },
316
+ },
317
+ css: {
318
+ preprocessorOptions: {
319
+ scss: {
320
+ silenceDeprecations: ['legacy-js-api'],
321
+ api: 'modern-compiler',
322
+ ${createScssOptions(output)} },
323
+ },
324
+ },
325
+ }
326
+ })
327
+ `;
328
+ }
329
+ /**
330
+ * 创建 Vite 配置的 import 区块。
331
+ * @param output atom 合并后的输出模型
332
+ * @returns import 文本
333
+ */
334
+ function createViteConfigImports(output) {
335
+ return [
336
+ '/**',
337
+ ' * Vite 配置文件',
338
+ ' * 由 create-app 在生成阶段按已选能力合成。',
339
+ ' */',
340
+ '',
341
+ 'import process from \'node:process\'',
342
+ 'import { fileURLToPath, URL } from \'node:url\'',
343
+ 'import type { PluginOption } from \'vite\'',
344
+ 'import { defineConfig, loadEnv } from \'vite\'',
345
+ ...output.vite.imports,
346
+ ].join('\n');
347
+ }
348
+ /**
349
+ * 创建 SCSS 扩展配置代码。
350
+ * @param output atom 合并后的输出模型
351
+ * @returns 已缩进并带结尾换行的 SCSS 配置片段
352
+ */
353
+ function createScssOptions(output) {
354
+ if (output.vite.scssOptions.length === 0) {
355
+ return '';
356
+ }
357
+ return `${indentLines(output.vite.scssOptions, 10)}\n`;
358
+ }
359
+ /**
360
+ * 按指定空格数缩进代码行。
361
+ * @param lines 代码行或多行代码块数组
362
+ * @param spaces 缩进空格数
363
+ * @returns 缩进后的代码文本
364
+ */
365
+ function indentLines(lines, spaces) {
366
+ if (lines.length === 0) {
367
+ return '';
368
+ }
369
+ const prefix = ' '.repeat(spaces);
370
+ return lines
371
+ .flatMap(line => line.split('\n'))
372
+ .map(line => (line ? `${prefix}${line}` : ''))
373
+ .join('\n');
374
+ }
375
+ /**
376
+ * 清理透明 Vite 配置不再需要的黑盒依赖。
377
+ * @param targetDir 生成项目根目录
378
+ * @throws {Error} 如果 package.json 读取或写入失败
379
+ */
380
+ function removeViteBlackBoxDependencies(targetDir) {
381
+ const packageJsonPath = path.join(targetDir, 'package.json');
382
+ if (!fs.existsSync(packageJsonPath)) {
383
+ throw new Error(`生成项目缺少 package.json: ${packageJsonPath}`);
384
+ }
385
+ const packageJson = fs.readJsonSync(packageJsonPath);
386
+ removeDependencies(packageJson.dependencies);
387
+ removeDependencies(packageJson.devDependencies);
388
+ fs.writeJsonSync(packageJsonPath, packageJson, { spaces: 2 });
389
+ fs.appendFileSync(packageJsonPath, '\n');
390
+ }
391
+ /**
392
+ * 从依赖集合中删除脚手架黑盒 Vite 配置依赖。
393
+ * @param dependencies package.json 中的依赖字段
394
+ */
395
+ function removeDependencies(dependencies) {
396
+ if (!dependencies) {
397
+ return;
398
+ }
399
+ for (const dependency of REMOVED_VITE_BLACK_BOX_DEPS) {
400
+ delete dependencies[dependency];
401
+ }
402
+ }
@@ -5,6 +5,7 @@
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { FILE_CONSTANTS } from "../constants/index.js";
8
+ import { PROJECT_ATOM_FILE } from "./projectAtom.js";
8
9
  import { deepMerge } from "../utils/deepMerge.js";
9
10
  import { validatePath } from "../utils/file.js";
10
11
  import { sortDependencies } from "../utils/sortDependencies.js";
@@ -45,6 +46,10 @@ export function renderTemplate(src, dest) {
45
46
  if (filename.endsWith(FILE_CONSTANTS.EJS_EXTENSION)) {
46
47
  return;
47
48
  }
49
+ // 跳过项目输出 atom,atom 只供脚手架生成阶段读取
50
+ if (filename === PROJECT_ATOM_FILE) {
51
+ return;
52
+ }
48
53
  // 处理 package.json - 深度合并
49
54
  if (filename === FILE_CONSTANTS.PACKAGE_JSON) {
50
55
  renderPackageJson(src, dest);
@@ -7,6 +7,7 @@ import fs from 'node:fs';
7
7
  import path from 'node:path';
8
8
  import { FILE_CONSTANTS, FRAMEWORKS } from "../constants/index.js";
9
9
  import { renderCommonFeatures, renderFrameworkFeatures, renderMicroFrontendFeatures, } from "../core/feature.js";
10
+ import { finalizeProjectOutput } from "../core/projectOutput.js";
10
11
  import { renderTemplate, updatePackageJsonMetadata } from "../core/template.js";
11
12
  import { emptyDir, getTemplatesDir } from "../utils/file.js";
12
13
  // ============================================================================
@@ -75,7 +76,9 @@ export async function generateProject(config) {
75
76
  // 3. 更新 package.json 元数据字段
76
77
  const packageJsonPath = path.join(targetDir, FILE_CONSTANTS.PACKAGE_JSON);
77
78
  updatePackageJsonMetadata(packageJsonPath, config.projectName, config.description, config.author, config.packageManager);
78
- // 4. 清理包管理器特定文件(只有 yarn 需要 .yarnrc.yml)
79
+ // 4. 生成最终入口和 Vite 配置,移除脚手架内部 loader
80
+ await finalizeProjectOutput(config);
81
+ // 5. 清理包管理器特定文件(只有 yarn 需要 .yarnrc.yml)
79
82
  if (config.packageManager !== 'yarn') {
80
83
  const yarnrcPath = path.join(targetDir, '.yarnrc.yml');
81
84
  if (fs.existsSync(yarnrcPath)) {
@@ -11,10 +11,8 @@
11
11
  */
12
12
  export declare const MOLUOXIXI_DEPS: {
13
13
  readonly '@moluoxixi/eslint-config': "latest";
14
- readonly '@moluoxixi/vite-config': "latest";
15
14
  readonly '@moluoxixi/ajax-package': "latest";
16
15
  readonly '@moluoxixi/class-names': "latest";
17
- readonly '@moluoxixi/css-module-global-root-plugin': "latest";
18
16
  };
19
17
  /**
20
18
  * 微前端引擎类型定义
@@ -11,10 +11,8 @@
11
11
  */
12
12
  export const MOLUOXIXI_DEPS = {
13
13
  '@moluoxixi/eslint-config': 'latest',
14
- '@moluoxixi/vite-config': 'latest',
15
14
  '@moluoxixi/ajax-package': 'latest',
16
15
  '@moluoxixi/class-names': 'latest',
17
- '@moluoxixi/css-module-global-root-plugin': 'latest',
18
16
  };
19
17
  /**
20
18
  * 微前端引擎类型定义