@moluoxixi/create-app 2.0.404 → 2.0.406

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 (129) hide show
  1. package/dist/commands/create.js +0 -1
  2. package/dist/generators/react.js +0 -2
  3. package/dist/generators/vue.js +0 -2
  4. package/dist/test.js +8 -0
  5. package/dist/utils/deepMerge.js +1 -1
  6. package/dist/utils/featureMapping.d.ts +2 -2
  7. package/dist/utils/featureMapping.js +3 -5
  8. package/dist/utils/generateFrameworkProject.d.ts +0 -4
  9. package/dist/utils/generateFrameworkProject.js +1 -1
  10. package/dist/utils/install.js +1 -1
  11. package/dist/utils/prompts.js +4 -30
  12. package/dist/utils/renderTemplate.js +9 -4
  13. package/package.json +2 -1
  14. package/templates/common/base/.gitmodules +4 -0
  15. package/templates/common/base/package.json +2 -0
  16. package/templates/common/base/vite.config.ts.ejs +13 -2
  17. package/templates/common/features/husky/package.json +2 -1
  18. package/templates/react/base/package.json +3 -1
  19. package/templates/react/{features/qiankun → base}/src/qiankun/index.ts +4 -0
  20. package/templates/react/base/src/stores/index.ts +5 -0
  21. package/templates/react/base/src/stores/user.ts +55 -0
  22. package/templates/react/{base/src/router/index.tsx.ejs → features/manualRoutes/src/router/index.tsx} +6 -5
  23. package/templates/react/features/pageRoutes/src/router/index.tsx +30 -0
  24. package/templates/vue/base/package.json +5 -1
  25. package/templates/vue/base/src/App.vue +1 -0
  26. package/templates/vue/base/src/assets/styles/base.scss +69 -0
  27. package/templates/vue/base/src/assets/styles/custom.scss +40 -0
  28. package/templates/vue/base/src/assets/styles/tailwind.scss +3 -0
  29. package/templates/vue/base/src/layouts/index.ts +22 -0
  30. package/templates/vue/base/src/main.ts.ejs +1 -0
  31. package/templates/vue/base/src/router/layout.vue +15 -0
  32. package/templates/vue/base/src/stores/index.ts +6 -0
  33. package/templates/vue/base/src/stores/modules/system.ts +51 -0
  34. package/templates/vue/base/src/stores/modules/user.ts +41 -0
  35. package/templates/vue/base/src/utils/index.ts +5 -0
  36. package/templates/vue/base/src/utils/modifyComponent.tsx +43 -0
  37. package/templates/vue/base/tsconfig.app.json +25 -16
  38. package/templates/vue/base/tsconfig.base.json +29 -22
  39. package/templates/vue/base/tsconfig.json +11 -11
  40. package/templates/vue/base/tsconfig.node.json +14 -14
  41. package/templates/vue/features/element-plus/src/assets/styles/element/fixQiankun.scss +10 -0
  42. package/templates/vue/features/element-plus/src/assets/styles/element/index.scss +3 -0
  43. package/templates/vue/features/element-plus/src/components/SubMenu/src/_types/index.ts +1 -5
  44. package/templates/vue/features/element-plus/src/components/SubMenu/src/_types/props.ts +16 -10
  45. package/templates/vue/features/element-plus/src/components/SubMenu/src/index.vue +60 -23
  46. package/templates/vue/features/element-plus/src/layouts/element.vue +106 -70
  47. package/templates/vue/features/manualRoutes/package.json +7 -0
  48. package/templates/vue/features/manualRoutes/src/router/index.ts +45 -0
  49. package/templates/vue/features/manualRoutes/src/router/layout.vue +11 -5
  50. package/templates/vue/features/manualRoutes/src/stores/index.ts +6 -0
  51. package/templates/vue/features/manualRoutes/src/stores/modules/system.ts +51 -0
  52. package/templates/vue/features/manualRoutes/src/stores/modules/user.ts +41 -0
  53. package/templates/vue/features/pageRoutes/package.json +4 -1
  54. package/templates/vue/features/pageRoutes/src/router/index.ts +46 -0
  55. package/templates/vue/features/pageRoutes/src/router/layout.vue +15 -0
  56. package/templates/vue/features/pageRoutes/src/stores/index.ts +6 -0
  57. package/templates/vue/features/pageRoutes/src/stores/modules/system.ts +51 -0
  58. package/templates/vue/features/pageRoutes/src/stores/modules/user.ts +41 -0
  59. package/templates/vue/features/sentry/package.json +3 -1
  60. package/templates/vue/features/sentry/src/stores/index.ts +13 -0
  61. package/templates/react/features/qiankun/package.json +0 -5
  62. package/templates/vue/base/src/router/index.ts.ejs +0 -36
  63. package/templates/vue/features/pinia/package.json +0 -7
  64. package/templates/vue/features/pinia/src/stores/index.ts +0 -15
  65. package/templates/vue/features/pinia/src/stores/system.ts +0 -59
  66. package/templates/vue/features/pinia/src/stores/user.ts +0 -56
  67. package/templates/vue/features/qiankun/node_modules/.bin/jiti +0 -17
  68. package/templates/vue/features/qiankun/node_modules/.bin/jiti.CMD +0 -12
  69. package/templates/vue/features/qiankun/node_modules/.bin/jiti.ps1 +0 -41
  70. package/templates/vue/features/qiankun/node_modules/.bin/sass +0 -17
  71. package/templates/vue/features/qiankun/node_modules/.bin/sass.CMD +0 -12
  72. package/templates/vue/features/qiankun/node_modules/.bin/sass.ps1 +0 -41
  73. package/templates/vue/features/qiankun/node_modules/.bin/terser +0 -17
  74. package/templates/vue/features/qiankun/node_modules/.bin/terser.CMD +0 -12
  75. package/templates/vue/features/qiankun/node_modules/.bin/terser.ps1 +0 -41
  76. package/templates/vue/features/qiankun/node_modules/.bin/tsc +0 -17
  77. package/templates/vue/features/qiankun/node_modules/.bin/tsc.CMD +0 -12
  78. package/templates/vue/features/qiankun/node_modules/.bin/tsc.ps1 +0 -41
  79. package/templates/vue/features/qiankun/node_modules/.bin/tsserver +0 -17
  80. package/templates/vue/features/qiankun/node_modules/.bin/tsserver.CMD +0 -12
  81. package/templates/vue/features/qiankun/node_modules/.bin/tsserver.ps1 +0 -41
  82. package/templates/vue/features/qiankun/node_modules/.bin/tsx +0 -17
  83. package/templates/vue/features/qiankun/node_modules/.bin/tsx.CMD +0 -12
  84. package/templates/vue/features/qiankun/node_modules/.bin/tsx.ps1 +0 -41
  85. package/templates/vue/features/qiankun/node_modules/.bin/vite +0 -17
  86. package/templates/vue/features/qiankun/node_modules/.bin/vite.CMD +0 -12
  87. package/templates/vue/features/qiankun/node_modules/.bin/vite.ps1 +0 -41
  88. package/templates/vue/features/qiankun/node_modules/.bin/yaml +0 -17
  89. package/templates/vue/features/qiankun/node_modules/.bin/yaml.CMD +0 -12
  90. package/templates/vue/features/qiankun/node_modules/.bin/yaml.ps1 +0 -41
  91. package/templates/vue/features/qiankun/package.json +0 -5
  92. package/templates/vue/features/qiankun/src/qiankun/index.ts +0 -74
  93. package/templates/vue/features/router/node_modules/.bin/tsc +0 -17
  94. package/templates/vue/features/router/node_modules/.bin/tsc.CMD +0 -12
  95. package/templates/vue/features/router/node_modules/.bin/tsc.ps1 +0 -41
  96. package/templates/vue/features/router/node_modules/.bin/tsserver +0 -17
  97. package/templates/vue/features/router/node_modules/.bin/tsserver.CMD +0 -12
  98. package/templates/vue/features/router/node_modules/.bin/tsserver.ps1 +0 -41
  99. package/templates/vue/features/router/package.json +0 -5
  100. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/jiti +0 -0
  101. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/jiti.CMD +0 -0
  102. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/jiti.ps1 +0 -0
  103. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/sass +0 -0
  104. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/sass.CMD +0 -0
  105. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/sass.ps1 +0 -0
  106. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/terser +0 -0
  107. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/terser.CMD +0 -0
  108. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/terser.ps1 +0 -0
  109. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsc +0 -0
  110. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsc.CMD +0 -0
  111. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsc.ps1 +0 -0
  112. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsserver +0 -0
  113. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsserver.CMD +0 -0
  114. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsserver.ps1 +0 -0
  115. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsx +0 -0
  116. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsx.CMD +0 -0
  117. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/tsx.ps1 +0 -0
  118. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/vite +0 -0
  119. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/vite.CMD +0 -0
  120. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/vite.ps1 +0 -0
  121. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/yaml +0 -0
  122. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/yaml.CMD +0 -0
  123. /package/templates/{react/features/qiankun → vue/features/manualRoutes}/node_modules/.bin/yaml.ps1 +0 -0
  124. /package/templates/vue/features/{pinia → pageRoutes}/node_modules/.bin/tsc +0 -0
  125. /package/templates/vue/features/{pinia → pageRoutes}/node_modules/.bin/tsc.CMD +0 -0
  126. /package/templates/vue/features/{pinia → pageRoutes}/node_modules/.bin/tsc.ps1 +0 -0
  127. /package/templates/vue/features/{pinia → pageRoutes}/node_modules/.bin/tsserver +0 -0
  128. /package/templates/vue/features/{pinia → pageRoutes}/node_modules/.bin/tsserver.CMD +0 -0
  129. /package/templates/vue/features/{pinia → pageRoutes}/node_modules/.bin/tsserver.ps1 +0 -0
@@ -37,7 +37,6 @@ export async function createProject(projectName) {
37
37
  console.log(chalk.gray(` UI 组件库: ${chalk.white(config.uiLibrary)}`));
38
38
  console.log(chalk.gray(` 路由模式: ${chalk.white(config.routeMode)}`));
39
39
  console.log(chalk.gray(` 国际化: ${chalk.white(config.i18n ? '是' : '否')}`));
40
- console.log(chalk.gray(` 微前端: ${chalk.white(config.qiankun ? '是' : '否')}`));
41
40
  console.log(chalk.gray(` 错误监控: ${chalk.white(config.sentry ? '是' : '否')}`));
42
41
  console.log(chalk.gray(` 包管理器: ${chalk.white(config.packageManager)}`));
43
42
  console.log('');
@@ -13,7 +13,5 @@ export async function generateReactProject(config) {
13
13
  generateFrameworkProject(config, {
14
14
  mainTemplate: 'src/main.tsx.ejs',
15
15
  mainOutput: 'src/main.tsx',
16
- routerTemplate: 'src/router/index.tsx.ejs',
17
- routerOutput: 'src/router/index.tsx',
18
16
  });
19
17
  }
@@ -13,7 +13,5 @@ export async function generateVueProject(config) {
13
13
  generateFrameworkProject(config, {
14
14
  mainTemplate: 'src/main.ts.ejs',
15
15
  mainOutput: 'src/main.ts',
16
- routerTemplate: 'src/router/index.ts.ejs',
17
- routerOutput: 'src/router/index.ts',
18
16
  });
19
17
  }
package/dist/test.js CHANGED
@@ -170,6 +170,7 @@ function createTestConfig(framework, uiLibrary, suffix, overrides) {
170
170
  /**
171
171
  * 生成测试项目
172
172
  * @param minimalOnly 是否只生成全量和最小配置
173
+ * @returns Promise<void>
173
174
  */
174
175
  async function generateTestProjects(minimalOnly = false) {
175
176
  const mode = minimalOnly ? '(仅全量和最小配置)' : '(全部组合)';
@@ -220,6 +221,8 @@ async function generateTestProjects(minimalOnly = false) {
220
221
  }
221
222
  /**
222
223
  * 检查 package.json 中是否有 catalog 引用(应该已经全部替换为实际版本号)
224
+ * @param projectDir 项目目录路径
225
+ * @returns 检查是否通过(true 表示通过,false 表示失败)
223
226
  */
224
227
  function checkPackageJsonVersions(projectDir) {
225
228
  const packageJsonPath = path.join(projectDir, FILE_CONSTANTS.PACKAGE_JSON);
@@ -371,6 +374,9 @@ async function showFileTrees() {
371
374
  }
372
375
  /**
373
376
  * 打印文件树
377
+ * @param dir 目录路径
378
+ * @param indent 缩进字符串
379
+ * @returns Promise<void>
374
380
  */
375
381
  async function printFileTree(dir, indent) {
376
382
  const items = fs.readdirSync(dir).sort();
@@ -390,6 +396,8 @@ async function printFileTree(dir, indent) {
390
396
  }
391
397
  /**
392
398
  * 主函数
399
+ * 执行测试项目生成、依赖审计和文件树显示
400
+ * @returns Promise<void>
393
401
  */
394
402
  async function main() {
395
403
  const { minimalOnly } = parseArgs();
@@ -33,7 +33,7 @@ export function deepMerge(target, source) {
33
33
  /**
34
34
  * 判断值是否为对象(非数组、非 null)
35
35
  * @param val 待判断的值
36
- * @returns 是否为对象
36
+ * @returns 是否为对象,排除数组和 null
37
37
  */
38
38
  function isObject(val) {
39
39
  return val !== null && typeof val === 'object' && !Array.isArray(val);
@@ -11,10 +11,10 @@ import type { FrameworkType } from '../types/index.ts';
11
11
  export declare function scanAllFeatures(framework: FrameworkType): string[];
12
12
  /**
13
13
  * 配置项到 feature 目录的映射(从 renderFeatures 提取)
14
- * @param framework 框架类型
14
+ * @param _framework 框架类型(已不再使用,保留以保持接口兼容性)
15
15
  * @returns 配置键到 feature 名称的映射对象
16
16
  */
17
- export declare function getConfigToFeatureMap(framework: FrameworkType): Record<string, string>;
17
+ export declare function getConfigToFeatureMap(_framework: FrameworkType): Record<string, string>;
18
18
  /**
19
19
  * 公共 features 映射
20
20
  * @returns 公共配置键到 feature 名称的映射对象
@@ -41,17 +41,15 @@ export function scanAllFeatures(framework) {
41
41
  }
42
42
  /**
43
43
  * 配置项到 feature 目录的映射(从 renderFeatures 提取)
44
- * @param framework 框架类型
44
+ * @param _framework 框架类型(已不再使用,保留以保持接口兼容性)
45
45
  * @returns 配置键到 feature 名称的映射对象
46
46
  */
47
- export function getConfigToFeatureMap(framework) {
47
+ export function getConfigToFeatureMap(_framework) {
48
48
  return {
49
- router: 'router',
50
- stateManagement: framework === 'vue' ? 'pinia' : 'zustand',
49
+ // router、stateManagement、qiankun 已内置到 base,不再作为 feature
51
50
  eslint: 'eslint',
52
51
  i18n: 'i18n',
53
52
  sentry: 'sentry',
54
- qiankun: 'qiankun',
55
53
  };
56
54
  }
57
55
  /**
@@ -12,10 +12,6 @@ interface EjsTemplateConfig {
12
12
  mainTemplate: string;
13
13
  /** 主入口文件输出路径(相对于目标目录) */
14
14
  mainOutput: string;
15
- /** 路由文件模板路径(相对于框架 base 目录) */
16
- routerTemplate: string;
17
- /** 路由文件输出路径(相对于目标目录) */
18
- routerOutput: string;
19
15
  }
20
16
  /**
21
17
  * 生成框架项目的通用函数
@@ -36,7 +36,7 @@ export function generateFrameworkProject(config, ejsConfig) {
36
36
  };
37
37
  const frameworkBasePath = path.join(templatesDir, framework, 'base');
38
38
  renderEjsToFile(path.join(frameworkBasePath, ejsConfig.mainTemplate), path.join(targetDir, ejsConfig.mainOutput), ejsData);
39
- renderEjsToFile(path.join(frameworkBasePath, ejsConfig.routerTemplate), path.join(targetDir, ejsConfig.routerOutput), ejsData);
39
+ // Router 已通过 feature 覆盖实现(manualRoutes/pageRoutes),不再使用 EJS
40
40
  // 6. 数据驱动生成 vite.config.ts(使用 EJS 模板)
41
41
  const viteConfigEjsData = getViteConfigEjsData(config);
42
42
  const commonBasePath = path.join(templatesDir, 'common', 'base');
@@ -12,7 +12,7 @@ const RETRY_DELAY_BASE_MS = 1000;
12
12
  * 验证命令参数安全性
13
13
  * @param packageManager 包管理器类型
14
14
  * @param cwd 工作目录
15
- * @throws {Error} 如果参数不安全
15
+ * @throws {Error} 如果包管理器类型不支持或路径不安全
16
16
  */
17
17
  function validateInstallParams(packageManager, cwd) {
18
18
  // 验证包管理器类型
@@ -113,14 +113,7 @@ export async function collectProjectConfig(projectName) {
113
113
  }
114
114
  },
115
115
  },
116
- // 是否启用路由
117
- {
118
- type: 'confirm',
119
- name: 'router',
120
- message: '是否启用路由 (vue-router/react-router-dom)?',
121
- default: true,
122
- },
123
- // 路由模式(仅在启用路由时询问)
116
+ // 路由模式(路由已内置,只需选择模式)
124
117
  {
125
118
  type: 'list',
126
119
  name: 'routeMode',
@@ -129,18 +122,6 @@ export async function collectProjectConfig(projectName) {
129
122
  { name: '文件系统路由 (vite-plugin-pages)', value: 'file-system' },
130
123
  { name: '手动配置路由', value: 'manual' },
131
124
  ],
132
- when: (answers) => answers.router === true,
133
- },
134
- // 是否启用状态管理
135
- {
136
- type: 'confirm',
137
- name: 'stateManagement',
138
- message: (answers) => {
139
- return answers.framework === 'vue'
140
- ? '是否启用状态管理 (Pinia)?'
141
- : '是否启用状态管理 (Zustand)?';
142
- },
143
- default: true,
144
125
  },
145
126
  // 是否启用国际化
146
127
  {
@@ -149,13 +130,6 @@ export async function collectProjectConfig(projectName) {
149
130
  message: '是否启用国际化 (i18n)?',
150
131
  default: true,
151
132
  },
152
- // 是否启用微前端
153
- {
154
- type: 'confirm',
155
- name: 'qiankun',
156
- message: '是否启用微前端 (qiankun)?',
157
- default: false,
158
- },
159
133
  // 是否启用错误监控
160
134
  {
161
135
  type: 'confirm',
@@ -198,10 +172,10 @@ export async function collectProjectConfig(projectName) {
198
172
  framework: answers.framework,
199
173
  uiLibrary: answers.uiLibrary,
200
174
  routeMode: answers.routeMode || 'manual',
201
- router: answers.router,
202
- stateManagement: answers.stateManagement,
175
+ router: true, // 路由已内置
176
+ stateManagement: true, // 状态管理已内置
203
177
  i18n: answers.i18n,
204
- qiankun: answers.qiankun,
178
+ qiankun: true, // 微前端已内置
205
179
  sentry: answers.sentry,
206
180
  eslint: answers.eslint,
207
181
  gitHooks: answers.gitHooks,
@@ -23,13 +23,15 @@ export function renderTemplate(src, dest) {
23
23
  if (path.basename(src) === FILE_CONSTANTS.NODE_MODULES) {
24
24
  return;
25
25
  }
26
- fs.mkdirSync(dest, { recursive: true });
26
+ // 统一使用绝对路径,确保目录创建和文件复制使用相同的路径格式
27
+ const resolvedDest = path.resolve(dest);
28
+ fs.mkdirSync(resolvedDest, { recursive: true });
27
29
  for (const file of fs.readdirSync(src)) {
28
30
  // 验证文件名安全性
29
31
  if (file.includes('..') || file.includes('~')) {
30
32
  throw new Error(`不安全的文件名: ${file}`);
31
33
  }
32
- renderTemplate(path.resolve(src, file), path.resolve(dest, file));
34
+ renderTemplate(path.resolve(src, file), path.resolve(resolvedDest, file));
33
35
  }
34
36
  return;
35
37
  }
@@ -51,6 +53,9 @@ export function renderTemplate(src, dest) {
51
53
  // 处理特殊文件名转换(如 _gitignore -> .gitignore)
52
54
  const targetFilename = renameFile(filename);
53
55
  const targetPath = path.resolve(path.dirname(dest), targetFilename);
56
+ // 确保目标文件的父目录存在
57
+ // 虽然目录处理时已创建,但文件名重命名时路径可能不同,需要确保父目录存在
58
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
54
59
  // 普通文件直接复制(后面的会覆盖前面的)
55
60
  fs.copyFileSync(src, targetPath);
56
61
  }
@@ -106,7 +111,7 @@ function renderPackageJson(src, dest) {
106
111
  /**
107
112
  * 获取包管理器的默认版本号
108
113
  * @param packageManager 包管理器类型
109
- * @returns 包管理器版本字符串
114
+ * @returns 包管理器版本字符串,如果未找到则返回 pnpm 的默认版本
110
115
  */
111
116
  function getPackageManagerVersion(packageManager) {
112
117
  const versions = {
@@ -158,7 +163,7 @@ export function updatePackageJsonMetadata(packageJsonPath, projectName, descript
158
163
  * 重命名特殊文件
159
164
  * 某些文件不能以 . 开头存在于模板中,需要特殊处理
160
165
  * @param name 原始文件名
161
- * @returns 转换后的文件名
166
+ * @returns 转换后的文件名,_ 开头的文件会转换为 . 开头
162
167
  */
163
168
  function renameFile(name) {
164
169
  // _开头的文件转换为.开头
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moluoxixi/create-app",
3
- "version": "2.0.404",
3
+ "version": "2.0.406",
4
4
  "type": "module",
5
5
  "description": "Create Vue/React projects with atomic layered architecture",
6
6
  "main": "dist/index.js",
@@ -77,6 +77,7 @@
77
77
  "test:all": "tsx src/test.ts",
78
78
  "type-check": "tsc --noEmit",
79
79
  "lint:eslint": "eslint . --fix",
80
+ "submodule:update": "git submodule init && git submodule update --init --recursive",
80
81
  "lint-staged": "lint-staged",
81
82
  "commit": "git add . && git-cz",
82
83
  "version:patch": "pnpm version patch --no-git-tag-version",
@@ -0,0 +1,4 @@
1
+ [submodule ".cursor"]
2
+ path = .cursor
3
+ url = https://github.com/moluoxixi/AIRules.git
4
+ branch = main
@@ -9,6 +9,8 @@
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",
13
+ "prepare": "pnpm submodule:update",
12
14
  "build": "vite build --mode production",
13
15
  "build:zip": "vite build --mode production && tsx scripts/build.mts",
14
16
  "preview": "vite preview",
@@ -60,12 +60,23 @@ export default ViteConfig(
60
60
  scss: {
61
61
  silenceDeprecations: ['legacy-js-api'],
62
62
  api: 'modern-compiler',
63
+ <% if (uiLibrary === 'element-plus') { -%>
64
+ additionalData: (source: string, filename: string) => {
65
+ if (filename.includes('assets/styles/element/index.scss')) {
66
+ return `$namespace : ${appCode || 'el'};
67
+ ${source}`
68
+ }
69
+ else {
70
+ return source
71
+ }
72
+ },
73
+ <% } -%>
63
74
  },
64
75
  postcss: {
65
76
  plugins: [
66
77
  cssModuleGlobalRootPlugin() as any,
67
- ]
68
- }
78
+ ],
79
+ },
69
80
  },
70
81
  },
71
82
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "scripts": {
3
- "prepare": "node .husky/install.mjs",
3
+ "prepare": "pnpm submodule:update && node .husky/install.mjs",
4
4
  "lint-staged": "lint-staged",
5
5
  "commit": "git add . && git-cz"
6
6
  },
@@ -20,6 +20,7 @@
20
20
  "devDependencies": {
21
21
  "@commitlint/cli": "^19.8.0",
22
22
  "@commitlint/config-conventional": "^19.8.0",
23
+ "@commitlint/types": "^19.8.0",
23
24
  "commitizen": "^4.3.1",
24
25
  "cz-customizable": "^7.4.0",
25
26
  "husky": "^9.1.7",
@@ -5,7 +5,9 @@
5
5
  },
6
6
  "dependencies": {
7
7
  "react": "^18.3.1",
8
- "react-dom": "^18.3.1"
8
+ "react-dom": "^18.3.1",
9
+ "vite-plugin-qiankun": "^1.0.15",
10
+ "@remix-run/router": "^1.23.0"
9
11
  },
10
12
  "devDependencies": {
11
13
  "@moluoxixi/css-module-global-root-plugin": "latest",
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Qiankun 微前端配置
3
+ */
4
+
1
5
  import type { ReactNode } from 'react'
2
6
  import type { Router } from '@remix-run/router'
3
7
  import {
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Zustand 状态管理配置
3
+ */
4
+
5
+ export * from './user'
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 用户状态管理
3
+ * 基于 Zustand
4
+ */
5
+
6
+ import { create } from 'zustand'
7
+ import { persist } from 'zustand/middleware'
8
+
9
+ /**
10
+ * 用户信息接口
11
+ */
12
+ interface UserInfo {
13
+ /** 用户 ID */
14
+ id: string
15
+ /** 用户名 */
16
+ username: string
17
+ /** 邮箱 */
18
+ email: string
19
+ /** 头像 URL(可选) */
20
+ avatar?: string
21
+ /** 角色列表 */
22
+ roles: string[]
23
+ }
24
+
25
+ /**
26
+ * 用户状态接口
27
+ */
28
+ interface UserState {
29
+ /** 用户信息 */
30
+ userInfo: UserInfo | null
31
+ /** 认证 token */
32
+ token: string
33
+ /** 设置用户信息 */
34
+ setUserInfo: (info: UserInfo | null) => void
35
+ /** 设置 token */
36
+ setToken: (token: string) => void
37
+ /** 清除用户信息 */
38
+ clearUser: () => void
39
+ }
40
+
41
+ export const useUserStore = create<UserState>()(
42
+ persist(
43
+ set => ({
44
+ userInfo: null,
45
+ token: '',
46
+ setUserInfo: info => set({ userInfo: info }),
47
+ setToken: token => set({ token }),
48
+ clearUser: () => set({ userInfo: null, token: '' }),
49
+ }),
50
+ {
51
+ name: 'user-storage',
52
+ partialize: state => ({ token: state.token }),
53
+ },
54
+ ),
55
+ )
@@ -1,19 +1,21 @@
1
1
  /**
2
2
  * 路由配置
3
+ * 手动配置路由模式
3
4
  */
4
5
 
5
6
  import { createBrowserRouter, createHashRouter } from 'react-router-dom'
6
- <% if (routeMode === 'file-system') { -%>
7
- import routes from '~react-pages'
8
- <% } else { -%>
9
7
  import { routes } from './routes'
10
- <% } -%>
11
8
 
12
9
  interface RouterConfig {
13
10
  historyMode?: 'hash' | 'history'
14
11
  basename?: string
15
12
  }
16
13
 
14
+ /**
15
+ * 创建路由实例
16
+ * @param config 路由配置
17
+ * @returns 路由实例
18
+ */
17
19
  export function createRouter(config: RouterConfig = {}) {
18
20
  const { historyMode = 'history', basename } = config
19
21
 
@@ -25,4 +27,3 @@ export function createRouter(config: RouterConfig = {}) {
25
27
  }
26
28
 
27
29
  export { routes }
28
-
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 路由配置
3
+ * 文件系统路由模式(基于 vite-plugin-pages)
4
+ */
5
+
6
+ import { createBrowserRouter, createHashRouter } from 'react-router-dom'
7
+ // @ts-expect-error - vite-plugin-pages 自动生成
8
+ import routes from '~react-pages'
9
+
10
+ interface RouterConfig {
11
+ historyMode?: 'hash' | 'history'
12
+ basename?: string
13
+ }
14
+
15
+ /**
16
+ * 创建路由实例
17
+ * @param config 路由配置
18
+ * @returns 路由实例
19
+ */
20
+ export function createRouter(config: RouterConfig = {}) {
21
+ const { historyMode = 'history', basename } = config
22
+
23
+ if (historyMode === 'hash') {
24
+ return createHashRouter(routes, { basename })
25
+ }
26
+
27
+ return createBrowserRouter(routes, { basename })
28
+ }
29
+
30
+ export { routes }
@@ -4,7 +4,11 @@
4
4
  "type-check": "vue-tsc --noEmit"
5
5
  },
6
6
  "dependencies": {
7
- "vue": "^3.5.13"
7
+ "vue": "^3.5.13",
8
+ "vite-plugin-qiankun": "^1.0.15",
9
+ "pinia": "^2.2.7",
10
+ "pinia-plugin-persistedstate": "^3.2.1",
11
+ "vue-router": "^4.4.5"
8
12
  },
9
13
  "devDependencies": {
10
14
  "@moluoxixi/css-module-global-root-plugin": "latest",
@@ -6,6 +6,7 @@
6
6
  /**
7
7
  * 根组件
8
8
  */
9
+ import { RouterView } from 'vue-router'
9
10
  </script>
10
11
 
11
12
  <style scoped>
@@ -0,0 +1,69 @@
1
+ :root {
2
+ --primary-color: #3a77ff; /* 主色调 */
3
+ --primary-color-1: #3a81ff; /* 辅助色1 */
4
+ --primary-color-2: #518fff; /* 辅助色2 */
5
+ --primary-color-3: #53a0fd; /* 辅助色3 */
6
+ --primary-color-4: #f7faff; /* 辅助色4 */
7
+ --success-color: #0eb67f; /* 辅助色5 */
8
+ --success-color-1: #f6fffc; /* 辅助色6 */
9
+ --warning-color: #f5ab01; /* 提醒色 */
10
+ --danger-color: #ef6b53; /* 警告色 */
11
+
12
+ /* 文字颜色 */
13
+ --text-color: #2a3651;
14
+ --text-color-1: #29354f;
15
+ --text-color-disable: #a9aeb9;
16
+ --text-color-choose: #3a77ff;
17
+ --text-color-white: white;
18
+
19
+ /* 边框色 */
20
+ --border-color-1: #dcdfe6;
21
+ --border-color-2: #b1b6bd;
22
+ --border-color-3: #e3e6e9;
23
+ --border-color-4: #e0e4e8;
24
+ --border-color-5: #0317c4bf;
25
+ --border-color-6: #7ba4ff;
26
+
27
+ /* 背景色 */
28
+ --bg-color-1: #f1f2f4;
29
+ --bg-color-2: #fafbfc;
30
+ --bg-color-3: #29354f;
31
+ --bg-color-4: #f5f7fa;
32
+ --bg-color-5: #f6f9ff;
33
+ --bg-color-6: #ebf2ff;
34
+ }
35
+
36
+ *,
37
+ *::before,
38
+ *::after {
39
+ box-sizing: border-box;
40
+ margin: 0;
41
+ }
42
+
43
+ ::-webkit-scrollbar {
44
+ width: 6px;
45
+ height: 6px;
46
+ }
47
+
48
+ ::-webkit-scrollbar-thumb {
49
+ background-color: #dddee0; /* 设置滑块的颜色 */
50
+ border-radius: 5px; /* 设置滑块的圆角 */
51
+ }
52
+
53
+ body {
54
+ color: var(--text-color);
55
+ transition:
56
+ color 0.5s,
57
+ background-color 0.5s;
58
+ font-size: 14px;
59
+ font-family: SourceHanSans-Regular, serif;
60
+ }
61
+
62
+ #app {
63
+ margin: 0;
64
+ padding: 0;
65
+ font-weight: normal;
66
+ background: #f1f2f4;
67
+ height: 100%;
68
+ overflow-y: auto;
69
+ }
@@ -0,0 +1,40 @@
1
+ .text-bold {
2
+ font-family: SourceHanSans-Semibold, serif;
3
+ font-weight: bold;
4
+ }
5
+
6
+ .text-medium {
7
+ font-family: SourceHanSans-Medium, serif;
8
+ }
9
+
10
+ .text-regular {
11
+ font-family: SourceHanSans-Regular, serif;
12
+ }
13
+
14
+ .text-light {
15
+ font-family: SourceHanSans-Light, serif;
16
+ }
17
+
18
+ .box-shadow {
19
+ box-shadow: 0 2px 10px 0 rgb(52 81 212 / 20%);
20
+ }
21
+
22
+ .rounded-0 {
23
+ border-radius: 0;
24
+ }
25
+
26
+ .rounded-4 {
27
+ border-radius: 4px;
28
+ }
29
+
30
+ .rounded-8 {
31
+ border-radius: 8px;
32
+ }
33
+
34
+ .rounded-12 {
35
+ border-radius: 12px;
36
+ }
37
+
38
+ .rounded-16 {
39
+ border-radius: 16px;
40
+ }
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -2,3 +2,25 @@
2
2
  * 布局组件导出
3
3
  * 注意:具体的布局组件在对应的 UI 库 feature 中
4
4
  */
5
+ import type { App, Component } from 'vue'
6
+
7
+ const layoutFiles = import.meta.glob('./*.vue', { eager: true, import: 'default' })
8
+ const layouts = Object.keys(layoutFiles).reduce((modules, modulePath) => {
9
+ const nameArr: string[] = modulePath.split('/')
10
+ const name: string | undefined
11
+ = nameArr.at(-1) === 'index.vue' ? nameArr.at(-2) : nameArr.at(-1)?.slice(0, -4)
12
+ const layout: Component = layoutFiles[modulePath] as Component
13
+ if (!layout)
14
+ return modules
15
+ if (name) {
16
+ modules[name!] = layout as Component
17
+ }
18
+ return modules
19
+ }, {} as any)
20
+ layouts.install = function (app: App) {
21
+ const layoutNames = Object.keys(layouts)
22
+ layoutNames.forEach((name) => {
23
+ app.component(name, layouts[name!])
24
+ })
25
+ }
26
+ export default layouts
@@ -21,6 +21,7 @@ import getRouter from './router'
21
21
  // 导入样式文件
22
22
  <% if (uiLibrary === 'element-plus') { -%>
23
23
  import '@/assets/styles/element/index.scss'
24
+ import '@/assets/styles/element/fixQiankun.scss'
24
25
  <% } -%>
25
26
  import '@/assets/styles/main.scss'
26
27
  import '@/assets/fonts/index.css'
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <component :is="layout" />
3
+ </template>
4
+
5
+ <script lang="ts" setup>
6
+ import { computed } from 'vue'
7
+ import layouts from '@/layouts'
8
+ import { useSystemStore } from '@/stores/modules/system'
9
+
10
+ const systemInfo = useSystemStore()
11
+ const layoutType = computed(() => systemInfo.layout)
12
+ const layout = computed(() => layouts[layoutType.value])
13
+ </script>
14
+
15
+ <style lang="scss" scoped></style>