pandax 0.0.1

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 (90) hide show
  1. package/README.md +83 -0
  2. package/bin/pandax.js +592 -0
  3. package/package.json +33 -0
  4. package/skills/pandax-frontend-api-mock/SKILL.md +62 -0
  5. package/skills/pandax-frontend-architecture/SKILL.md +1239 -0
  6. package/skills/pandax-frontend-component-review/SKILL.md +114 -0
  7. package/skills/pandax-frontend-requirement/SKILL.md +142 -0
  8. package/skills/pandax-frontend-standards/SKILL.md +468 -0
  9. package/skills/pandax-frontend-use-modal/SKILL.md +621 -0
  10. package/templates/pandax-monorepo/.editorconfig +16 -0
  11. package/templates/pandax-monorepo/.husky/commit-msg +2 -0
  12. package/templates/pandax-monorepo/.husky/pre-commit +2 -0
  13. package/templates/pandax-monorepo/.prettierrc.json +28 -0
  14. package/templates/pandax-monorepo/apps/base/env.d.ts +1 -0
  15. package/templates/pandax-monorepo/apps/base/index.html +13 -0
  16. package/templates/pandax-monorepo/apps/base/package.json +30 -0
  17. package/templates/pandax-monorepo/apps/base/src/App.vue +15 -0
  18. package/templates/pandax-monorepo/apps/base/src/layouts/default-layout/index.vue +23 -0
  19. package/templates/pandax-monorepo/apps/base/src/main.ts +31 -0
  20. package/templates/pandax-monorepo/apps/base/src/router/index.ts +22 -0
  21. package/templates/pandax-monorepo/apps/base/src/stores/index.ts +15 -0
  22. package/templates/pandax-monorepo/apps/base/src/styles/global.scss +19 -0
  23. package/templates/pandax-monorepo/apps/base/src/styles/variables.scss +4 -0
  24. package/templates/pandax-monorepo/apps/base/src/types/wujie.d.ts +16 -0
  25. package/templates/pandax-monorepo/apps/base/src/views/home/index.vue +21 -0
  26. package/templates/pandax-monorepo/apps/base/tsconfig.json +25 -0
  27. package/templates/pandax-monorepo/apps/base/tsconfig.node.json +11 -0
  28. package/templates/pandax-monorepo/apps/base/vite.config.ts +26 -0
  29. package/templates/pandax-monorepo/apps/main/env.d.ts +1 -0
  30. package/templates/pandax-monorepo/apps/main/index.html +13 -0
  31. package/templates/pandax-monorepo/apps/main/package.json +32 -0
  32. package/templates/pandax-monorepo/apps/main/src/App.vue +15 -0
  33. package/templates/pandax-monorepo/apps/main/src/layouts/MicroApp.vue +29 -0
  34. package/templates/pandax-monorepo/apps/main/src/layouts/default-layout/index.vue +48 -0
  35. package/templates/pandax-monorepo/apps/main/src/main.ts +27 -0
  36. package/templates/pandax-monorepo/apps/main/src/router/index.ts +22 -0
  37. package/templates/pandax-monorepo/apps/main/src/stores/index.ts +23 -0
  38. package/templates/pandax-monorepo/apps/main/src/styles/global.scss +23 -0
  39. package/templates/pandax-monorepo/apps/main/src/styles/variables.scss +8 -0
  40. package/templates/pandax-monorepo/apps/main/src/views/home/index.vue +25 -0
  41. package/templates/pandax-monorepo/apps/main/tsconfig.json +25 -0
  42. package/templates/pandax-monorepo/apps/main/tsconfig.node.json +11 -0
  43. package/templates/pandax-monorepo/apps/main/vite.config.ts +24 -0
  44. package/templates/pandax-monorepo/commitlint.config.js +38 -0
  45. package/templates/pandax-monorepo/eslint.config.js +61 -0
  46. package/templates/pandax-monorepo/package.json +50 -0
  47. package/templates/pandax-monorepo/packages/components/package.json +20 -0
  48. package/templates/pandax-monorepo/packages/components/src/PandaButton.vue +15 -0
  49. package/templates/pandax-monorepo/packages/components/src/PandaCard.vue +16 -0
  50. package/templates/pandax-monorepo/packages/components/src/index.ts +2 -0
  51. package/templates/pandax-monorepo/packages/core/package.json +20 -0
  52. package/templates/pandax-monorepo/packages/core/src/index.ts +2 -0
  53. package/templates/pandax-monorepo/packages/core/src/request.ts +24 -0
  54. package/templates/pandax-monorepo/packages/core/src/utils.ts +7 -0
  55. package/templates/pandax-monorepo/packages/hooks/package.json +19 -0
  56. package/templates/pandax-monorepo/packages/hooks/src/index.ts +2 -0
  57. package/templates/pandax-monorepo/packages/hooks/src/useCounter.ts +27 -0
  58. package/templates/pandax-monorepo/packages/hooks/src/useToggle.ts +19 -0
  59. package/templates/pandax-monorepo/packages/styles/package.json +19 -0
  60. package/templates/pandax-monorepo/packages/styles/src/index.ts +1 -0
  61. package/templates/pandax-monorepo/packages/styles/src/uno.ts +19 -0
  62. package/templates/pandax-monorepo/packages/styles/src/variables.scss +14 -0
  63. package/templates/pandax-monorepo/pnpm-workspace.yaml +32 -0
  64. package/templates/pandax-monorepo/turbo.json +23 -0
  65. package/templates/vue3/.eslintrc.cjs +16 -0
  66. package/templates/vue3/.prettierrc +7 -0
  67. package/templates/vue3/env.d.ts +1 -0
  68. package/templates/vue3/index.html +13 -0
  69. package/templates/vue3/package.json +34 -0
  70. package/templates/vue3/src/App.vue +14 -0
  71. package/templates/vue3/src/api/index.ts +27 -0
  72. package/templates/vue3/src/assets/.gitkeep +1 -0
  73. package/templates/vue3/src/components/.gitkeep +1 -0
  74. package/templates/vue3/src/composables/.gitkeep +1 -0
  75. package/templates/vue3/src/constants/.gitkeep +1 -0
  76. package/templates/vue3/src/directives/.gitkeep +1 -0
  77. package/templates/vue3/src/layouts/default-layout/index.vue +33 -0
  78. package/templates/vue3/src/locales/.gitkeep +1 -0
  79. package/templates/vue3/src/main.ts +17 -0
  80. package/templates/vue3/src/router/index.ts +17 -0
  81. package/templates/vue3/src/services/.gitkeep +1 -0
  82. package/templates/vue3/src/stores/index.ts +12 -0
  83. package/templates/vue3/src/styles/global.scss +18 -0
  84. package/templates/vue3/src/styles/variables.scss +17 -0
  85. package/templates/vue3/src/types/global.d.ts +9 -0
  86. package/templates/vue3/src/utils/format.ts +11 -0
  87. package/templates/vue3/src/views/home/index.vue +19 -0
  88. package/templates/vue3/tsconfig.json +25 -0
  89. package/templates/vue3/tsconfig.node.json +10 -0
  90. package/templates/vue3/vite.config.ts +20 -0
@@ -0,0 +1,1239 @@
1
+ ---
2
+ name: "pandax-frontend-architecture"
3
+ category: "frontend"
4
+ description: "设计前端项目架构与技术方案。Invoke when 新项目技术选型、划分业务模块、设计目录结构、制定前后端交互方案、或评估前端框架与工程化方案。"
5
+ ---
6
+
7
+ # Pandax 前端架构设计
8
+
9
+ 本 skill 用于规范前端项目整体架构设计,包括技术选型、目录结构、模块划分、状态管理、路由设计、组件分层、性能与工程化策略。
10
+
11
+ ## 触发条件
12
+
13
+ - 启动一个新前端项目,需要做技术选型
14
+ - 需要划分业务模块或微前端边界
15
+ - 需要设计或调整项目目录结构
16
+ - 需要制定前后端数据交互方案
17
+ - 需要评估是否引入新框架、新工具或重构现有架构
18
+ - 项目规模扩大,现有架构出现明显瓶颈
19
+
20
+ ## 设计原则
21
+
22
+ 1. **单一职责**:每个模块、每个目录只做一类事
23
+ 2. **关注点分离**:UI、状态、数据、路由、样式分层清晰
24
+ 3. **可测试**:核心逻辑不依赖 UI,便于单元测试
25
+ 4. **可扩展**:新增功能对现有模块影响最小
26
+ 5. **可维护**:目录命名和文件组织一眼能看懂
27
+ 6. **性能优先**:首屏加载、代码分割、缓存策略提前考虑
28
+
29
+ ## 推荐技术栈
30
+
31
+ 本 skill 默认以 **Vue 3 最新版 + Vite 8 最新版** 为基础技术栈,如需 React 方案,需显式说明。
32
+
33
+ | 层级 | 推荐方案 | 说明 |
34
+ |------|---------|------|
35
+ | 框架 | Vue 3(最新版) | Composition API + `<script setup>` |
36
+ | 构建 | Vite 8(最新版) | 快速 HMR、原生 ESM |
37
+ | 语言 | TypeScript 6.0(暂不升 7,详见 [工程规范配置](#工程规范配置)) | 强制类型,提升可维护性 |
38
+ | 状态 | Pinia | Vue 官方推荐,类型友好 |
39
+ | 路由 | Vue Router 4 | 按模块懒加载 |
40
+ | 样式 | UnoCSS + SCSS | 原子化 CSS + 变量/模块化 |
41
+ | 请求 | Axios + 统一封装 | 集中处理错误、loading、token |
42
+ | 规范 | ESLint 9 + flat config + Prettier + commitlint + husky | 强制类型、代码风格、提交规范,详见 [工程规范配置](#工程规范配置) |
43
+ | UI 库 | Element Plus | 后台管理系统首选 |
44
+
45
+ ## 项目骨架生成流程
46
+
47
+ 当用户要求"生成前端项目骨架"、"初始化项目"、"创建 Vue3 项目"时,按以下步骤执行:
48
+
49
+ ### 步骤 1:询问骨架类型
50
+
51
+ 必须向用户确认要创建哪种骨架,提供以下选项:
52
+
53
+ | 选项 | 说明 |
54
+ |------|------|
55
+ | **A. 单应用骨架** | 一个独立的 Vue3 应用,适合中小型项目 |
56
+ | **B. Monorepo + 微前端主应用 + 微前端应用** | 一主多从的完整微前端仓库 |
57
+ | **C. 微前端主应用** | 只生成 wujie 基座主应用 |
58
+ | **D. 微前端应用** | 只生成可被 wujie 加载的子应用 |
59
+
60
+ 如果用户未明确选择,默认推荐 **A. 单应用骨架**。
61
+
62
+ ### 步骤 2:确认技术栈
63
+
64
+ 默认技术栈为:Vue 3 最新版 + Vite 8 最新版 + TypeScript + Pinia + UnoCSS + SCSS + Axios + Element Plus。
65
+
66
+ 询问用户是否需要调整:
67
+ - 是否需要 Element Plus?
68
+ - 是否需要 vue-i18n 国际化?
69
+ - 是否需要 wujie 微前端相关依赖?(B/C/D 必含)
70
+ - **包名前缀**:packages 共享包与 apps 应用包名均不带 scope,默认前缀 `pandax-`(如 `pandax-core`、`pandax-base`)。用户可指定任意前缀(如 `myorg-`),生成时统一替换;目录扁平化放在 `packages/{core,components,hooks,styles}/`,不使用 `@scope/` 子目录
71
+
72
+ ### 步骤 3:读取 pandax-frontend-standards 规范
73
+
74
+ 在生成目录和文件之前,必须先读取 `.trae/skills/pandax-frontend-standards/SKILL.md`,确保生成的骨架符合 Pandax 前端规范:
75
+
76
+ - 目录命名:是否使用 `views/`、`components/`、`services/`、`constants/`、`locales/` 等约定
77
+ - 文件命名:组件目录是否全小写 + 短横线,文件是否 `index.vue`、`Prop.ts`、`Type.ts`、`index.module.scss`
78
+ - 组件结构:是否使用 `<script setup lang="ts">`,是否按 region 组织代码
79
+ - 页面组织:`views/{module}/pages/` 结构,新增/编辑是否默认抽屉
80
+ - API 分层:`src/api/request.ts` + `src/services/` 两层结构
81
+ - 样式规范:SCSS 变量、`index.module.scss`、UnoCSS 原子类
82
+ - 国际化:`src/locales/` 目录
83
+ - 常量:`src/constants/` 目录
84
+
85
+ 如果项目中已有 `docs/standards/` 文档,优先读取项目内文档;否则使用 `pandax-frontend-standards` 中的默认约定。
86
+
87
+ ### 步骤 4:按骨架类型和规范生成目录和文件
88
+
89
+ 生成完成后,给出:
90
+ 1. 目录结构
91
+ 2. 核心文件内容
92
+ 3. 安装依赖命令
93
+ 4. 启动命令
94
+ 5. 本次生成所依据的 Pandax 规范条目
95
+
96
+ ## 目录结构
97
+
98
+ ```text
99
+ src/
100
+ ├── api/ # 底层请求封装(axios 实例、拦截器)
101
+ ├── assets/ # 静态资源
102
+ ├── components/ # 通用业务组件
103
+ ├── composables/ # Vue 组合式函数 / React Hooks
104
+ ├── constants/ # 全局常量、枚举、配置项
105
+ ├── directives/ # 自定义指令
106
+ ├── layouts/ # 页面布局组件
107
+ ├── locales/ # 国际化资源文件
108
+ ├── router/ # 路由配置
109
+ ├── services/ # 业务 API 对接层,按模块拆分
110
+ ├── stores/ # 全局状态管理
111
+ ├── styles/ # 全局样式、变量、mixins
112
+ ├── types/ # 全局类型定义
113
+ ├── utils/ # 通用工具函数
114
+ └── views/ # 页面级组件,按业务模块组织
115
+ ```
116
+
117
+ ### 关键目录说明
118
+
119
+ | 目录 | 职责 | 示例 |
120
+ |------|------|------|
121
+ | `api/` | 底层请求封装 | `request.ts`(axios 实例、拦截器) |
122
+ | `services/` | 业务 API 对接 | `user.ts`(用户相关接口调用) |
123
+ | `constants/` | 常量、枚举、配置 | `enum.ts`、`config.ts` |
124
+ | `locales/` | 国际化资源 | `zh-CN.json`、`en-US.json` |
125
+ | `types/` | 全局 TypeScript 类型 | `global.d.ts`、`user.ts` |
126
+ | `views/` | 页面组件 | `user/pages/list/index.vue` |
127
+
128
+ ## 模块划分策略
129
+
130
+ ### 按业务领域划分(推荐)
131
+
132
+ 页面按业务模块组织在 `views/` 下,每个模块包含自己的页面、私有组件和类型定义。
133
+
134
+ ```text
135
+ src/views/
136
+ ├── user/ # 用户模块
137
+ │ ├── components/ # 模块私有组件
138
+ │ ├── pages/ # 页面
139
+ │ │ ├── list/
140
+ │ │ ├── detail/
141
+ │ │ └── form/
142
+ │ └── Type.ts # 模块类型
143
+ ├── order/ # 订单模块
144
+ └── product/ # 产品模块
145
+ ```
146
+
147
+ ### 适用场景
148
+
149
+ | 项目规模 | 推荐结构 |
150
+ |---------|---------|
151
+ | 小型项目(<10 页面) | `views/` 平铺,页面直接放 `views/` 下 |
152
+ | 中型项目(10-50 页面) | `views/{module}/pages/` 按业务模块组织 |
153
+ | 大型项目 / 多团队 | Monorepo + 微前端(wujie) |
154
+
155
+ ## A. 单应用骨架生成
156
+
157
+ ### 目录结构
158
+
159
+ ```text
160
+ my-app/
161
+ ├── package.json
162
+ ├── vite.config.ts
163
+ ├── tsconfig.json
164
+ ├── tsconfig.node.json
165
+ ├── env.d.ts
166
+ ├── index.html
167
+ ├── eslint.config.js # Vue 3 官方 ESLint 9 flat config
168
+ ├── .prettierrc.json
169
+ ├── .editorconfig
170
+ ├── commitlint.config.js # Conventional Commits
171
+ ├── .gitignore
172
+ ├── .husky/ # Git hooks
173
+ │ ├── pre-commit # 跑 lint-staged
174
+ │ └── commit-msg # 跑 commitlint
175
+ └── src/
176
+ ├── api/
177
+ │ └── request.ts
178
+ ├── assets/
179
+ ├── components/
180
+ ├── composables/
181
+ ├── constants/
182
+ ├── directives/
183
+ ├── layouts/
184
+ │ └── default-layout/
185
+ │ ├── index.vue
186
+ │ └── index.module.scss
187
+ ├── locales/
188
+ │ └── zh-CN.json
189
+ ├── router/
190
+ │ └── index.ts
191
+ ├── services/
192
+ ├── stores/
193
+ │ └── index.ts
194
+ ├── styles/
195
+ │ ├── global.scss
196
+ │ └── variables.scss
197
+ ├── types/
198
+ │ └── global.d.ts
199
+ ├── utils/
200
+ ├── views/
201
+ │ └── home/
202
+ │ ├── index.vue
203
+ │ ├── Prop.ts
204
+ │ ├── Type.ts
205
+ │ └── index.module.scss
206
+ ├── App.vue
207
+ └── main.ts
208
+ ```
209
+
210
+ ### package.json
211
+
212
+ ```json
213
+ {
214
+ "name": "my-app",
215
+ "version": "0.1.0",
216
+ "type": "module",
217
+ "scripts": {
218
+ "dev": "vite",
219
+ "build": "vue-tsc --noEmit && vite build",
220
+ "preview": "vite preview",
221
+ "lint": "eslint .",
222
+ "lint:fix": "eslint . --fix",
223
+ "format": "prettier --write \"**/*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs,json,scss,md,yml,yaml}\"",
224
+ "prepare": "husky",
225
+ "commit": "cz"
226
+ },
227
+ "dependencies": {
228
+ "vue": "^3.5.0",
229
+ "vue-router": "^4.5.0",
230
+ "pinia": "^2.3.0",
231
+ "axios": "^1.8.0",
232
+ "element-plus": "^2.9.0",
233
+ "@element-plus/icons-vue": "^2.3.0"
234
+ },
235
+ "devDependencies": {
236
+ "@vitejs/plugin-vue": "^5.2.0",
237
+ "vite": "^8.0.0",
238
+ "vue-tsc": "^3.3.11",
239
+ "typescript": "^6.0.3",
240
+ "eslint": "^9.18.0",
241
+ "eslint-plugin-vue": "^9.33.0",
242
+ "@vue/eslint-config-typescript": "^14.9.0",
243
+ "@vue/eslint-config-prettier": "^10.1.0",
244
+ "prettier": "^3.5.0",
245
+ "husky": "^9.1.7",
246
+ "lint-staged": "^15.3.0",
247
+ "@commitlint/cli": "^19.6.1",
248
+ "@commitlint/config-conventional": "^19.6.0",
249
+ "commitizen": "^4.3.1",
250
+ "cz-conventional-changelog": "^3.3.0",
251
+ "sass": "^1.86.0",
252
+ "unocss": "^66.0.0",
253
+ "@unocss/preset-uno": "^66.0.0"
254
+ },
255
+ "lint-staged": {
256
+ "*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs}": "eslint --fix",
257
+ "*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs,json,scss,md,yml,yaml}": "prettier --write"
258
+ },
259
+ "config": {
260
+ "commitizen": {
261
+ "path": "cz-conventional-changelog"
262
+ }
263
+ }
264
+ }
265
+ ```
266
+
267
+ ### vite.config.ts
268
+
269
+ ```ts
270
+ import { defineConfig } from 'vite';
271
+ import vue from '@vitejs/plugin-vue';
272
+ import { resolve } from 'path';
273
+ import UnoCSS from 'unocss/vite';
274
+
275
+ export default defineConfig({
276
+ plugins: [vue(), UnoCSS()],
277
+ resolve: {
278
+ alias: {
279
+ '@': resolve(__dirname, 'src'),
280
+ },
281
+ },
282
+ css: {
283
+ preprocessorOptions: {
284
+ scss: {
285
+ additionalData: `@use "@/styles/variables.scss" as *;`,
286
+ },
287
+ },
288
+ },
289
+ });
290
+ ```
291
+
292
+ ### main.ts
293
+
294
+ ```ts
295
+ import { createApp } from 'vue';
296
+ import { createPinia } from 'pinia';
297
+ import ElementPlus from 'element-plus';
298
+ import 'element-plus/dist/index.css';
299
+ import 'virtual:uno.css';
300
+ import './styles/global.scss';
301
+
302
+ import App from './App.vue';
303
+ import router from './router';
304
+
305
+ const app = createApp(App);
306
+
307
+ app.use(createPinia());
308
+ app.use(router);
309
+ app.use(ElementPlus);
310
+
311
+ app.mount('#app');
312
+ ```
313
+
314
+ ### 输出要求
315
+
316
+ 生成单应用骨架时,必须包含:
317
+ 1. `package.json` 使用 Vue 3 最新版、Vite 8 最新版
318
+ 2. `vite.config.ts` 配置 `@` 别名、UnoCSS、SCSS 全局变量
319
+ 3. `src/api/request.ts` 统一 axios 封装
320
+ 4. `src/router/index.ts` Vue Router 4 基础路由
321
+ 5. `src/stores/index.ts` Pinia Store 示例
322
+ 6. `src/styles/variables.scss` + `global.scss`
323
+ 7. `src/views/home/index.vue` 首页示例
324
+ 8. **工程规范配置**:按 [工程规范配置](#工程规范配置) 章节生成 `eslint.config.js`、`.prettierrc.json`、`.editorconfig`、`commitlint.config.js`、`.husky/`、`.gitignore`,`package.json` 包含 `prepare`/`commit`/`lint`/`lint:fix`/`format` 脚本与 `lint-staged`/`config.commitizen` 字段
325
+ 9. **规范依据说明**:列出本次生成遵循的 `pandax-frontend-standards` 条目,如目录结构、文件命名、组件结构、API 分层、ESLint 与 commit 规范等
326
+
327
+ ## B. Monorepo + 微前端主应用 + 微前端应用
328
+
329
+ 当项目包含多个子应用、组件库、工具库,且需要通过 wujie 聚合为统一平台时,使用 Monorepo + 微前端骨架。
330
+
331
+ ### 目录结构
332
+
333
+ ```text
334
+ pandax-monorepo/
335
+ ├── package.json # 根 package.json,管理 workspace + 规范类依赖
336
+ ├── pnpm-workspace.yaml # pnpm workspace 配置 + catalog 版本统一
337
+ ├── turbo.json # Turborepo 任务编排
338
+ ├── eslint.config.js # Vue 3 官方 ESLint 9 flat config(全仓库共用)
339
+ ├── .prettierrc.json
340
+ ├── .editorconfig
341
+ ├── commitlint.config.js # Conventional Commits
342
+ ├── .gitignore
343
+ ├── .husky/ # Git hooks(全仓库共用)
344
+ │ ├── pre-commit # 跑 lint-staged
345
+ │ └── commit-msg # 跑 commitlint
346
+ ├── apps/
347
+ │ ├── main/ # wujie 主应用(基座)
348
+ │ └── base/ # 子应用:基础应用(示例)
349
+ └── packages/
350
+ ├── core/ # 核心依赖:请求封装、类型定义、工具函数(包名 pandax-core)
351
+ ├── components/ # 通用组件库(包名 pandax-components)
352
+ ├── hooks/ # 通用 Hooks / Composables(包名 pandax-hooks)
353
+ └── styles/ # 主题、变量、全局样式(包名 pandax-styles)
354
+ ```
355
+
356
+ ### 根 package.json
357
+
358
+ ```json
359
+ {
360
+ "name": "pandax-monorepo",
361
+ "version": "1.0.0",
362
+ "private": true,
363
+ "packageManager": "pnpm@10.0.0",
364
+ "type": "module",
365
+ "scripts": {
366
+ "dev": "turbo run dev --parallel",
367
+ "build": "turbo run build",
368
+ "build:main": "pnpm --filter pandax-main build",
369
+ "build:apps": "turbo run build --filter=!./apps/main",
370
+ "lint": "turbo run lint",
371
+ "lint:fix": "turbo run lint:fix",
372
+ "format": "prettier --write \"**/*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs,json,scss,md,yml,yaml}\"",
373
+ "typecheck": "turbo run typecheck",
374
+ "clean": "pnpm -r exec rm -rf node_modules dist .turbo",
375
+ "prepare": "husky",
376
+ "commit": "cz"
377
+ },
378
+ "devDependencies": {
379
+ "turbo": "^2.4.0",
380
+ "eslint": "^9.18.0",
381
+ "eslint-plugin-vue": "^9.33.0",
382
+ "@vue/eslint-config-typescript": "^14.9.0",
383
+ "@vue/eslint-config-prettier": "^10.1.0",
384
+ "prettier": "^3.5.0",
385
+ "husky": "^9.1.7",
386
+ "lint-staged": "^15.3.0",
387
+ "@commitlint/cli": "^19.6.1",
388
+ "@commitlint/config-conventional": "^19.6.0",
389
+ "commitizen": "^4.3.1",
390
+ "cz-conventional-changelog": "^3.3.0"
391
+ },
392
+ "lint-staged": {
393
+ "*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs}": "eslint --fix",
394
+ "*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs,json,scss,md,yml,yaml}": "prettier --write"
395
+ },
396
+ "config": {
397
+ "commitizen": {
398
+ "path": "cz-conventional-changelog"
399
+ }
400
+ }
401
+ }
402
+ ```
403
+
404
+ > 规范类工具统一在根安装,子包 `devDependencies` 只保留各自构建相关依赖(`vite`、`@vitejs/plugin-vue`、`vue-tsc`、`sass`、`unocss` 等),不再重复声明 `eslint` 系列。
405
+
406
+ ### pnpm-workspace.yaml
407
+
408
+ ```yaml
409
+ packages:
410
+ - 'apps/*'
411
+ - 'packages/*'
412
+ ```
413
+
414
+ ### 依赖划分
415
+
416
+ | 包名 | 职责 |
417
+ |------|------|
418
+ | `pandax-core` | axios 封装、全局类型、常量、通用 utils |
419
+ | `pandax-components` | Button、Table、Form 等基础组件 |
420
+ | `pandax-hooks` | useModal、usePermission、useTable 等 |
421
+ | `pandax-styles` | UnoCSS 配置、SCSS 变量、主题 |
422
+
423
+ ### 主应用注册子应用
424
+
425
+ ```ts
426
+ // apps/main/src/main.ts
427
+ import { createApp } from 'vue';
428
+ import { createPinia } from 'pinia';
429
+ import { setupApp } from 'wujie';
430
+ import ElementPlus from 'element-plus';
431
+ import 'element-plus/dist/index.css';
432
+ import 'virtual:uno.css';
433
+
434
+ import App from './App.vue';
435
+ import router from './router';
436
+
437
+ setupApp({
438
+ name: 'base',
439
+ url: '//localhost:7101',
440
+ exec: true,
441
+ props: {
442
+ token: localStorage.getItem('token') || '',
443
+ },
444
+ });
445
+
446
+ const app = createApp(App);
447
+ app.use(createPinia());
448
+ app.use(router);
449
+ app.use(ElementPlus);
450
+ app.mount('#app');
451
+ ```
452
+
453
+ ### 输出要求
454
+
455
+ 生成 B 骨架时,必须包含:
456
+ 1. 根 `package.json` + `pnpm-workspace.yaml`,使用 pnpm workspace
457
+ 2. `apps/main/` wujie 主应用,含 `main.ts` 注册子应用、`router/index.ts`、`layouts/MicroApp.vue`
458
+ 3. 至少 1 个示例子应用:`apps/base/`,独立的 Vue 3 + Vite 8 应用
459
+ 4. `packages/core/`、`packages/components/`、`packages/hooks/`、`packages/styles/` 四个共享包(目录扁平化,包名 `pandax-core` 等无 scope,便于 npx 初始化时按需重命名)
460
+ 5. 子应用入口 `main.ts` 必须支持 `window.__POWERED_BY_WUJIE__` 两种运行方式
461
+ 6. **工程规范配置**:按 [工程规范配置](#工程规范配置) 章节生成根 `eslint.config.js`、`.prettierrc.json`、`.editorconfig`、`commitlint.config.js`、`.husky/`、`.gitignore`,规范类依赖统一放根 `devDependencies`
462
+ 7. **规范依据说明**:列出 Monorepo 目录命名、子应用文件结构、ESLint 与 commit 规范遵循的 `pandax-frontend-standards` 条目
463
+
464
+ ## 工程规范配置
465
+
466
+ 本章节统一说明 **Vue 3 官方 ESLint 检查规范 + Conventional Commits 提交规范** 的配置方式,A/B/C/D 四种骨架生成时必须遵循。Monorepo(B)配置统一放在根目录,单应用(A/C/D)配置放在项目根目录。
467
+
468
+ ### 工具链一览
469
+
470
+ | 工具 | 版本 | 职责 |
471
+ |------|------|------|
472
+ | `typescript` | ^6.0.3 | 类型检查(5.x → 7.0 官方过渡版本,详见下文「TypeScript 版本选择说明」) |
473
+ | `vue-tsc` | ^3.3.11 | `.vue` 文件类型检查(基于 Volar,peer `typescript >=5.0.0`) |
474
+ | `eslint` | ^9.18.0 | 代码静态检查(flat config) |
475
+ | `eslint-plugin-vue` | ^9.33.0 | Vue 3 官方推荐规则(`flat/recommended`) |
476
+ | `@vue/eslint-config-typescript` | ^14.9.0 | Vue + TS 集成规则(v14.9 起用 `withVueTs` + `vueTsConfigs` API) |
477
+ | `@vue/eslint-config-prettier` | ^10.1.0 | 关闭与 Prettier 冲突的格式规则 |
478
+ | `prettier` | ^3.5.0 | 代码格式化 |
479
+ | `husky` | ^9.1.7 | Git hooks 框架 |
480
+ | `lint-staged` | ^15.3.0 | 只对暂存区文件跑 lint/format |
481
+ | `@commitlint/cli` | ^19.6.1 | 校验 commit message |
482
+ | `@commitlint/config-conventional` | ^19.6.0 | Conventional Commits 默认规则 |
483
+ | `commitizen` + `cz-conventional-changelog` | ^4.3.1 / ^3.3.0 | 交互式 commit 向导 |
484
+
485
+ #### TypeScript 版本选择说明
486
+
487
+ | 版本 | 状态 | 是否采用 |
488
+ |------|------|---------|
489
+ | TS 5.x | 已过时 | 否 |
490
+ | **TS 6.0.3** | 最后一个 JS 编译器版本,官方推荐的 5.x → 7.0 过渡版本 | **是** |
491
+ | TS 7.0.2 | Go 编译器,10x 提速,但**未提供稳定 programmatic API** | 否(暂不升) |
492
+
493
+ **为什么暂不升 TS 7.0**:
494
+
495
+ - TS 7.0 不再暴露稳定的 programmatic API,要等 7.1(约 2026-10)才补齐
496
+ - vue-tsc / Volar 等 Vue 工具链依赖 TS 的 API 做 `.vue` 文件类型检查,直接升 7 会报 `ERR_PACKAGE_PATH_NOT_EXPORTED: Package subpath './lib/tsc' is not defined`(参考 [vuejs/language-tools#6124](https://github.com/vuejs/language-tools/issues/6124))
497
+ - 官方明确建议:Vue / Svelte / Astro / MDX 项目**停在 TS 6.0**,等 7.1
498
+ - TS 6.0 把 7.0 即将变成 hard error 的用法以 deprecation 警告形式暴露,提前迁移可让未来升 7.0 几乎零成本
499
+
500
+ **TS 7.1 发布后的升级路径**(约 2026-10):
501
+
502
+ 1. 等 vue-tsc 发布支持 TS 7 的稳定版本(追踪 [PR #6123](https://github.com/vuejs/language-tools/pull/6123))
503
+ 2. `pnpm-workspace.yaml` 把 `typescript: ^6.0.3` 改为 `^7.1.0`
504
+ 3. 检查 `tsconfig.json`:TS 7 默认 `strict: true`、`types: []`、`target: esnext`,移除 `target: es5`、`moduleResolution: node`、`baseUrl` 等 deprecated 选项
505
+ 4. 如工具链暂未跟进,可装 `@typescript/typescript6` 兼容包让 vue-tsc 走 `tsc6` 路径
506
+ 5. 跑 `pnpm typecheck && pnpm lint` 验证
507
+
508
+ ### 1. ESLint 9 flat config(`eslint.config.js`)
509
+
510
+ Vue 3 官方推荐 ESLint 9 + flat config 形式,禁止再使用旧式 `.eslintrc.*` + `--ext`。使用 `@vue/eslint-config-typescript` v14.9+ 的 `withVueTs` + `vueTsConfigs` API。
511
+
512
+ ```javascript
513
+ // eslint.config.js
514
+ import pluginVue from 'eslint-plugin-vue';
515
+ import { withVueTs, vueTsConfigs } from '@vue/eslint-config-typescript';
516
+ import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';
517
+
518
+ export default withVueTs(
519
+ // 1. 待 lint 的文件范围
520
+ { name: 'app/files-to-lint', files: ['**/*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs}'] },
521
+
522
+ // 2. Vue 3 官方推荐规则(含 vue 解析器)
523
+ pluginVue.configs['flat/recommended'],
524
+
525
+ // 3. TypeScript 推荐规则(不开 type-checked,类型检查交给 vue-tsc / tsc,保持 lint 速度)
526
+ // 如需深度类型感知 lint,可改为 vueTsConfigs.recommendedTypeChecked
527
+ vueTsConfigs.recommended,
528
+
529
+ // 4. 自定义规则(遵循 pandax-frontend-standards)
530
+ {
531
+ name: 'app/custom-rules',
532
+ rules: {
533
+ 'vue/multi-word-component-names': 'off',
534
+ 'vue/no-v-html': 'off',
535
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
536
+ '@typescript-eslint/no-explicit-any': 'warn',
537
+ 'no-console': ['warn', { allow: ['warn', 'error'] }],
538
+ 'no-debugger': 'error',
539
+ },
540
+ },
541
+
542
+ // 5. 忽略目录
543
+ {
544
+ name: 'app/files-to-ignore',
545
+ ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**', '**/.turbo/**', '**/node_modules/**', '**/*.d.ts'],
546
+ },
547
+
548
+ // 6. 关闭与 Prettier 冲突的格式规则(必须放最后)
549
+ skipFormatting,
550
+ );
551
+ ```
552
+
553
+ 子包 `lint` 脚本(ESLint 9 不再需要 `--ext`):
554
+
555
+ ```json
556
+ {
557
+ "scripts": {
558
+ "lint": "eslint .",
559
+ "lint:fix": "eslint . --fix"
560
+ }
561
+ }
562
+ ```
563
+
564
+ > Monorepo 中子包无需各自写 `eslint.config.js`,ESLint 9 会向上查找根配置自动应用。
565
+
566
+ ### 2. Prettier(`.prettierrc.json`)
567
+
568
+ ```json
569
+ {
570
+ "$schema": "https://json.schemastore.org/prettierrc",
571
+ "semi": false,
572
+ "singleQuote": true,
573
+ "trailingComma": "all",
574
+ "printWidth": 100,
575
+ "tabWidth": 2,
576
+ "endOfLine": "lf",
577
+ "arrowParens": "always",
578
+ "bracketSpacing": true,
579
+ "overrides": [
580
+ { "files": ["*.json", "*.json5", "*.jsonc"], "options": { "trailingComma": "none" } },
581
+ { "files": ["*.md", "*.mdx"], "options": { "proseWrap": "preserve", "printWidth": 120 } },
582
+ { "files": ["*.yml", "*.yaml"], "options": { "singleQuote": false } }
583
+ ]
584
+ }
585
+ ```
586
+
587
+ ### 3. EditorConfig(`.editorconfig`)
588
+
589
+ 与 Prettier 保持一致(`indent_size = 2`、`end_of_line = lf`、`charset = utf-8`)。
590
+
591
+ ### 4. commitlint(`commitlint.config.js`)
592
+
593
+ ```javascript
594
+ // commitlint.config.js
595
+ export default {
596
+ extends: ['@commitlint/config-conventional'],
597
+ rules: {
598
+ 'header-max-length': [2, 'always', 100],
599
+ 'type-enum': [
600
+ 2,
601
+ 'always',
602
+ ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert', 'wip'],
603
+ ],
604
+ 'type-empty': [2, 'never'],
605
+ 'subject-empty': [2, 'never'],
606
+ 'subject-full-stop': [2, 'never', '.'],
607
+ 'subject-case': [0],
608
+ },
609
+ };
610
+ ```
611
+
612
+ ### 5. Husky + lint-staged
613
+
614
+ 初始化:`pnpm dlx husky init`(或直接在根 `package.json` 配 `"prepare": "husky"`,运行 `pnpm install` 时自动安装 hooks)。
615
+
616
+ `.husky/pre-commit`(提交前对暂存区跑 ESLint + Prettier):
617
+
618
+ ```sh
619
+ pnpm exec lint-staged
620
+ ```
621
+
622
+ `.husky/commit-msg`(校验 commit message):
623
+
624
+ ```sh
625
+ pnpm exec commitlint --edit "$1"
626
+ ```
627
+
628
+ `package.json` 中的 `lint-staged` 字段:
629
+
630
+ ```json
631
+ {
632
+ "lint-staged": {
633
+ "*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs}": "eslint --fix",
634
+ "*.{ts,tsx,cts,mts,vue,js,jsx,cjs,mjs,json,scss,md,yml,yaml}": "prettier --write"
635
+ }
636
+ }
637
+ ```
638
+
639
+ ### 6. commitizen 交互式提交
640
+
641
+ `package.json` 中配置 adapter:
642
+
643
+ ```json
644
+ {
645
+ "config": {
646
+ "commitizen": {
647
+ "path": "cz-conventional-changelog"
648
+ }
649
+ },
650
+ "scripts": {
651
+ "commit": "cz"
652
+ }
653
+ }
654
+ ```
655
+
656
+ 使用 `pnpm commit` 代替 `git commit`,进入交互式向导选择 type / scope / subject / body / breaking change / footer。
657
+
658
+ ### 7. Conventional Commits 速查
659
+
660
+ | type | 含义 | 示例 |
661
+ |------|------|------|
662
+ | `feat` | 新功能 | `feat: 新增用户列表筛选` |
663
+ | `fix` | 修复 bug | `fix: 修复登录 token 失效` |
664
+ | `docs` | 文档变更 | `docs: 补充 useModal 使用示例` |
665
+ | `style` | 格式调整(不影响功能) | `style: 统一缩进为 2 空格` |
666
+ | `refactor` | 重构 | `refactor: 抽离 request 拦截器` |
667
+ | `perf` | 性能优化 | `perf: 列表使用虚拟滚动` |
668
+ | `test` | 测试 | `test: 补充 useCounter 单测` |
669
+ | `build` | 构建系统 / 外部依赖 | `build: 升级 vite 到 8.0` |
670
+ | `ci` | CI 配置 | `ci: 配置 GitHub Actions` |
671
+ | `chore` | 杂项 | `chore: 更新 .gitignore` |
672
+ | `revert` | 回滚 | `revert: 撤销用户模块改动` |
673
+
674
+ > 含 BREAKING CHANGE 的提交必须显式标注:`feat: 重构路由结构` + body 中 `BREAKING CHANGE: 路由配置字段从 routes 改为 children`,或用 `feat!: 重构路由结构` 简写。
675
+
676
+ ### 8. .gitignore 必备项
677
+
678
+ ```text
679
+ node_modules/
680
+ dist/
681
+ dist-ssr/
682
+ .turbo/
683
+ coverage/
684
+ *.log
685
+ .husky/_
686
+ ```
687
+
688
+ ### 工程规范配置输出要求
689
+
690
+ 生成任意骨架(A/B/C/D)时,工程规范部分必须包含:
691
+ 1. `eslint.config.js` 使用 Vue 3 官方 flat config 形式(`pluginVue.configs['flat/recommended']` + `@vue/eslint-config-typescript` + `@vue/eslint-config-prettier`)
692
+ 2. `.prettierrc.json` + `.editorconfig` 与 Prettier 配置一致
693
+ 3. `commitlint.config.js` 继承 `@commitlint/config-conventional`,type 枚举完整
694
+ 4. `.husky/pre-commit` 跑 `lint-staged`,`.husky/commit-msg` 跑 `commitlint`
695
+ 5. `package.json` 包含 `prepare`、`commit`、`lint`、`lint:fix`、`format` 脚本,以及 `lint-staged`、`config.commitizen` 字段
696
+ 6. Monorepo(B)规范类依赖统一放根 `devDependencies`,子包 `devDependencies` 只保留构建相关依赖
697
+
698
+ ## C. 微前端主应用
699
+
700
+ 只生成 wujie 基座主应用,用于承载和调度子应用。
701
+
702
+ ### 目录结构
703
+
704
+ ```text
705
+ apps/main/
706
+ ├── package.json
707
+ ├── vite.config.ts
708
+ ├── tsconfig.json
709
+ ├── tsconfig.node.json
710
+ ├── env.d.ts
711
+ ├── index.html
712
+ └── src/
713
+ ├── api/
714
+ │ └── request.ts
715
+ ├── assets/
716
+ ├── components/
717
+ ├── composables/
718
+ ├── constants/
719
+ ├── layouts/
720
+ │ ├── default-layout/
721
+ │ │ ├── index.vue
722
+ │ │ └── index.module.scss
723
+ │ └── MicroApp.vue
724
+ ├── router/
725
+ │ └── index.ts
726
+ ├── services/
727
+ ├── stores/
728
+ │ └── index.ts
729
+ ├── styles/
730
+ │ ├── global.scss
731
+ │ └── variables.scss
732
+ ├── types/
733
+ │ └── global.d.ts
734
+ ├── utils/
735
+ ├── views/
736
+ │ └── home/
737
+ │ └── index.vue
738
+ ├── App.vue
739
+ └── main.ts
740
+ ```
741
+
742
+ ### package.json
743
+
744
+ ```json
745
+ {
746
+ "name": "pandax-main",
747
+ "version": "0.1.0",
748
+ "type": "module",
749
+ "scripts": {
750
+ "dev": "vite --port 7000",
751
+ "build": "vue-tsc --noEmit && vite build",
752
+ "preview": "vite preview",
753
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
754
+ "typecheck": "vue-tsc --noEmit"
755
+ },
756
+ "dependencies": {
757
+ "vue": "^3.5.0",
758
+ "vue-router": "^4.5.0",
759
+ "pinia": "^2.3.0",
760
+ "wujie": "^1.0.25",
761
+ "wujie-vue3": "^1.0.25",
762
+ "axios": "^1.8.0",
763
+ "element-plus": "^2.9.0",
764
+ "@element-plus/icons-vue": "^2.3.0"
765
+ },
766
+ "devDependencies": {
767
+ "@vitejs/plugin-vue": "^5.2.0",
768
+ "vite": "^8.0.0",
769
+ "vue-tsc": "^3.3.11",
770
+ "typescript": "^6.0.3",
771
+ "eslint": "^8.57.0",
772
+ "@vue/eslint-config-typescript": "^13.0.0",
773
+ "eslint-plugin-vue": "^9.33.0",
774
+ "sass": "^1.86.0",
775
+ "unocss": "^66.0.0",
776
+ "@unocss/preset-uno": "^66.0.0"
777
+ }
778
+ }
779
+ ```
780
+
781
+ ### main.ts
782
+
783
+ ```ts
784
+ import { createApp } from 'vue';
785
+ import { createPinia } from 'pinia';
786
+ import { setupApp } from 'wujie';
787
+ import ElementPlus from 'element-plus';
788
+ import 'element-plus/dist/index.css';
789
+ import 'virtual:uno.css';
790
+ import './styles/global.scss';
791
+
792
+ import App from './App.vue';
793
+ import router from './router';
794
+
795
+ setupApp({
796
+ name: 'base',
797
+ url: '//localhost:7101',
798
+ exec: true,
799
+ props: { token: localStorage.getItem('token') || '' },
800
+ });
801
+
802
+ const app = createApp(App);
803
+ app.use(createPinia());
804
+ app.use(router);
805
+ app.use(ElementPlus);
806
+ app.mount('#app');
807
+ ```
808
+
809
+ ### 路由配置
810
+
811
+ ```ts
812
+ // apps/main/src/router/index.ts
813
+ import { createRouter, createWebHistory } from 'vue-router';
814
+
815
+ const routes = [
816
+ {
817
+ path: '/',
818
+ component: () => import('@/views/home/index.vue'),
819
+ },
820
+ {
821
+ path: '/base/:path(.*)',
822
+ component: () => import('@/layouts/MicroApp.vue'),
823
+ props: { name: 'base', url: '//localhost:7101' },
824
+ },
825
+ ];
826
+
827
+ export default createRouter({
828
+ history: createWebHistory(),
829
+ routes,
830
+ });
831
+ ```
832
+
833
+ ### MicroApp.vue 容器组件
834
+
835
+ ```vue
836
+ <!-- apps/main/src/layouts/MicroApp.vue -->
837
+ <script setup lang="ts">
838
+ import WujieVue from 'wujie-vue3';
839
+
840
+ interface Props {
841
+ name: string;
842
+ url: string;
843
+ }
844
+
845
+ const props = defineProps<Props>();
846
+ </script>
847
+
848
+ <template>
849
+ <div class="micro-app-container h-full w-full">
850
+ <WujieVue
851
+ :name="props.name"
852
+ :url="props.url"
853
+ :sync="true"
854
+ width="100%"
855
+ height="100%"
856
+ />
857
+ </div>
858
+ </template>
859
+
860
+ <style scoped lang="scss">
861
+ .micro-app-container {
862
+ position: relative;
863
+ overflow: hidden;
864
+ }
865
+ </style>
866
+ ```
867
+
868
+ ### 输出要求
869
+
870
+ 生成 C 骨架时,必须包含:
871
+ 1. `apps/main/package.json` 包含 `wujie`、`wujie-vue3` 依赖
872
+ 2. `apps/main/src/main.ts` 使用 `setupApp` 注册所有子应用
873
+ 3. `apps/main/src/router/index.ts` 配置子应用通配路由
874
+ 4. `apps/main/src/layouts/MicroApp.vue` 容器组件,使用 `wujie-vue3` 渲染子应用
875
+ 5. 基础单应用文件:`vite.config.ts`、Pinia Store、Axios 封装、首页示例
876
+ 6. **工程规范配置**:按 [工程规范配置](#工程规范配置) 章节生成 `eslint.config.js`、`.prettierrc.json`、`.editorconfig`、`commitlint.config.js`、`.husky/`、`.gitignore`,规范类依赖放 `devDependencies`,`package.json` 包含 `prepare`/`commit`/`lint`/`lint:fix`/`format` 脚本与 `lint-staged`/`config.commitizen` 字段
877
+ 7. **规范依据说明**:列出主应用目录结构、组件规范、ESLint 与 commit 规范遵循的 `pandax-frontend-standards` 条目
878
+
879
+ ## D. 微前端应用
880
+
881
+ 只生成可被 wujie 加载的子应用,每个子应用独立开发、独立部署。
882
+
883
+ ### 目录结构
884
+
885
+ ```text
886
+ apps/base/
887
+ ├── package.json
888
+ ├── vite.config.ts
889
+ ├── tsconfig.json
890
+ ├── tsconfig.node.json
891
+ ├── env.d.ts
892
+ ├── index.html
893
+ └── src/
894
+ ├── api/
895
+ │ └── request.ts
896
+ ├── assets/
897
+ ├── components/
898
+ ├── composables/
899
+ ├── constants/
900
+ ├── locales/
901
+ │ └── zh-CN.json
902
+ ├── router/
903
+ │ └── index.ts
904
+ ├── services/
905
+ ├── stores/
906
+ │ └── index.ts
907
+ ├── styles/
908
+ │ ├── global.scss
909
+ │ └── variables.scss
910
+ ├── types/
911
+ │ └── global.d.ts
912
+ ├── utils/
913
+ ├── views/
914
+ │ └── home/
915
+ │ ├── index.vue
916
+ │ ├── Prop.ts
917
+ │ ├── Type.ts
918
+ │ └── index.module.scss
919
+ ├── App.vue
920
+ └── main.ts
921
+ ```
922
+
923
+ ### package.json
924
+
925
+ ```json
926
+ {
927
+ "name": "pandax-base",
928
+ "version": "0.1.0",
929
+ "type": "module",
930
+ "scripts": {
931
+ "dev": "vite --port 7101",
932
+ "build": "vue-tsc --noEmit && vite build",
933
+ "preview": "vite preview --port 7101",
934
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
935
+ "typecheck": "vue-tsc --noEmit"
936
+ },
937
+ "dependencies": {
938
+ "vue": "^3.5.0",
939
+ "vue-router": "^4.5.0",
940
+ "pinia": "^2.3.0",
941
+ "axios": "^1.8.0",
942
+ "element-plus": "^2.9.0",
943
+ "@element-plus/icons-vue": "^2.3.0"
944
+ },
945
+ "devDependencies": {
946
+ "@vitejs/plugin-vue": "^5.2.0",
947
+ "vite": "^8.0.0",
948
+ "vue-tsc": "^3.3.11",
949
+ "typescript": "^6.0.3",
950
+ "eslint": "^8.57.0",
951
+ "@vue/eslint-config-typescript": "^13.0.0",
952
+ "eslint-plugin-vue": "^9.33.0",
953
+ "sass": "^1.86.0",
954
+ "unocss": "^66.0.0",
955
+ "@unocss/preset-uno": "^66.0.0"
956
+ }
957
+ }
958
+ ```
959
+
960
+ ### wujie 类型补充
961
+
962
+ ```ts
963
+ // apps/base/src/types/wujie.d.ts
964
+ declare global {
965
+ interface Window {
966
+ __POWERED_BY_WUJIE__?: boolean;
967
+ __WUJIE_MOUNT?: () => void;
968
+ __WUJIE_UNMOUNT?: () => void;
969
+ $wujie?: {
970
+ props?: Record<string, any>;
971
+ bus: {
972
+ $emit: (event: string, ...args: any[]) => void;
973
+ $on: (event: string, callback: (...args: any[]) => void) => void;
974
+ };
975
+ };
976
+ }
977
+ }
978
+
979
+ export {};
980
+ ```
981
+
982
+ ### 子应用入口 main.ts
983
+
984
+ ```ts
985
+ // apps/base/src/main.ts
986
+ import { createApp } from 'vue';
987
+ import { createPinia } from 'pinia';
988
+ import ElementPlus from 'element-plus';
989
+ import 'element-plus/dist/index.css';
990
+ import 'virtual:uno.css';
991
+ import './styles/global.scss';
992
+
993
+ import App from './App.vue';
994
+ import router from './router';
995
+
996
+ let app: ReturnType<typeof createApp> | null = null;
997
+
998
+ function mount() {
999
+ app = createApp(App);
1000
+ app.use(createPinia());
1001
+ app.use(router);
1002
+ app.use(ElementPlus);
1003
+ app.mount('#app');
1004
+ }
1005
+
1006
+ function unmount() {
1007
+ app?.unmount();
1008
+ app = null;
1009
+ }
1010
+
1011
+ // 被 wujie 加载时,暴露生命周期
1012
+ if (window.__POWERED_BY_WUJIE__) {
1013
+ window.__WUJIE_MOUNT = mount;
1014
+ window.__WUJIE_UNMOUNT = unmount;
1015
+ } else {
1016
+ // 独立运行
1017
+ mount();
1018
+ }
1019
+ ```
1020
+
1021
+ ### 运行方式说明
1022
+
1023
+ - **独立运行**:直接执行 `pnpm --filter pandax-base dev`,走 `else` 分支,作为普通 Vue 3 应用启动。
1024
+ - **被 wujie 加载**:wujie 注入 `window.__POWERED_BY_WUJIE__`,并自动调用 `window.__WUJIE_MOUNT` 和 `window.__WUJIE_UNMOUNT`。
1025
+
1026
+ ### 输出要求
1027
+
1028
+ 生成 D 骨架时,必须包含:
1029
+ 1. `apps/base/package.json` 使用 Vue 3 最新版、Vite 8 最新版
1030
+ 2. `apps/base/src/types/wujie.d.ts` 扩展 `Window` 类型
1031
+ 3. `apps/base/src/main.ts` 同时支持 `window.__POWERED_BY_WUJIE__` 和独立运行
1032
+ 4. `apps/base/vite.config.ts` 配置正确的 `base` 路径和 `@` 别名
1033
+ 5. 基础单应用文件:router、Pinia Store、Axios 封装、页面示例
1034
+ 6. **工程规范配置**:按 [工程规范配置](#工程规范配置) 章节生成 `eslint.config.js`、`.prettierrc.json`、`.editorconfig`、`commitlint.config.js`、`.husky/`、`.gitignore`,规范类依赖放 `devDependencies`,`package.json` 包含 `prepare`/`commit`/`lint`/`lint:fix`/`format` 脚本与 `lint-staged`/`config.commitizen` 字段
1035
+ 7. **规范依据说明**:列出子应用目录结构、组件规范、ESLint 与 commit 规范遵循的 `pandax-frontend-standards` 条目
1036
+
1037
+ ### 选型建议
1038
+
1039
+ | 场景 | 推荐方案 |
1040
+ |------|---------|
1041
+ | 单应用、小团队 | A. 单应用骨架 |
1042
+ | 多应用、统一技术栈、统一构建 | B. Monorepo + 微前端主应用 + 微前端应用 |
1043
+ | 只需要聚合已有子应用 | C. 微前端主应用 |
1044
+ | 已有主应用,需新增子应用 | D. 微前端应用 |
1045
+
1046
+ ## 状态管理
1047
+
1048
+ - **组件级状态**:使用 `ref` / `reactive` / `useState`
1049
+ - **跨组件状态**:使用 `provide/inject` 或 Context
1050
+ - **模块级状态**:使用 Pinia Store / Zustand,按模块拆分
1051
+ - **服务端状态**:优先使用 TanStack Query / SWR,避免手动维护
1052
+
1053
+ ## 路由设计
1054
+
1055
+ - 按模块组织路由文件
1056
+ - 路由懒加载,减少首屏体积
1057
+ - 统一处理 404、权限、白名单
1058
+ - 面包屑和菜单从路由配置派生
1059
+
1060
+ ```ts
1061
+ // src/router/modules/user.ts
1062
+ export default {
1063
+ path: '/user',
1064
+ component: () => import('@/layouts/default-layout/index.vue'),
1065
+ children: [
1066
+ { path: 'list', component: () => import('@/views/user/pages/list/index.vue') },
1067
+ { path: 'detail/:id', component: () => import('@/views/user/pages/detail/index.vue') },
1068
+ ],
1069
+ };
1070
+ ```
1071
+
1072
+ ## 组件分层
1073
+
1074
+ | 层级 | 职责 | 示例 |
1075
+ |------|------|------|
1076
+ | 基础组件 | 无业务逻辑,纯 UI | Button、Input、Modal |
1077
+ | 业务组件 | 封装业务逻辑 | UserForm、OrderTable |
1078
+ | 页面组件 | 组合业务组件,对接路由 | UserListPage |
1079
+ | 布局组件 | 页面框架 | DefaultLayout |
1080
+
1081
+ ## API 层设计
1082
+
1083
+ 采用两层结构:`api/` 负责底层请求封装,`services/` 负责业务 API 对接。
1084
+
1085
+ ```text
1086
+ src/
1087
+ ├── api/
1088
+ │ └── request.ts # axios 实例、拦截器、统一错误处理
1089
+ ├── services/
1090
+ │ ├── user.ts # 用户相关 API
1091
+ │ └── order.ts # 订单相关 API
1092
+ ├── types/
1093
+ │ ├── user.ts # 用户相关类型
1094
+ │ └── order.ts # 订单相关类型
1095
+ └── constants/
1096
+ └── api.ts # API 常量、枚举
1097
+ ```
1098
+
1099
+ ### 职责划分
1100
+
1101
+ | 层级 | 目录 | 职责 |
1102
+ |------|------|------|
1103
+ | 底层请求 | `src/api/` | axios 实例、拦截器、错误处理、token 注入 |
1104
+ | 业务接口 | `src/services/` | 按模块封装业务 API,调用 `request.ts` |
1105
+ | 类型定义 | `src/types/` | 请求参数、响应数据、业务模型类型 |
1106
+ | 常量配置 | `src/constants/` | API 路径常量、状态码枚举、配置项 |
1107
+
1108
+ ### 示例
1109
+
1110
+ ```ts
1111
+ // src/api/request.ts
1112
+ import axios from 'axios';
1113
+
1114
+ const request = axios.create({
1115
+ baseURL: import.meta.env.VITE_API_BASE_URL,
1116
+ timeout: 10000,
1117
+ });
1118
+
1119
+ request.interceptors.request.use((config) => {
1120
+ const token = localStorage.getItem('token');
1121
+ if (token) config.headers.Authorization = `Bearer ${token}`;
1122
+ return config;
1123
+ });
1124
+
1125
+ request.interceptors.response.use(
1126
+ (res) => res.data,
1127
+ (err) => {
1128
+ // 统一错误处理
1129
+ return Promise.reject(err);
1130
+ }
1131
+ );
1132
+
1133
+ export default request;
1134
+ ```
1135
+
1136
+ ```ts
1137
+ // src/services/user.ts
1138
+ import request from '@/api/request';
1139
+ import type { UserListParams, UserListResponse } from '@/types/user';
1140
+
1141
+ export function getUserList(params: UserListParams) {
1142
+ return request.get<UserListResponse>('/users', { params });
1143
+ }
1144
+
1145
+ export function createUser(data: Partial<UserListResponse['list'][0]>) {
1146
+ return request.post('/users', data);
1147
+ }
1148
+ ```
1149
+
1150
+ ## 国际化(i18n)
1151
+
1152
+ 国际化资源统一放在 `src/locales/` 目录下。
1153
+
1154
+ ```text
1155
+ src/locales/
1156
+ ├── zh-CN.json # 简体中文
1157
+ ├── en-US.json # 英文
1158
+ ├── ja-JP.json # 日文
1159
+ └── index.ts # i18n 初始化与加载
1160
+ ```
1161
+
1162
+ ### 推荐方案
1163
+
1164
+ | 框架 | 库 |
1165
+ |------|-----|
1166
+ | Vue 3 | vue-i18n |
1167
+ | React | react-i18next |
1168
+
1169
+ ### 资源文件格式
1170
+
1171
+ ```json
1172
+ {
1173
+ "common": {
1174
+ "save": "保存",
1175
+ "cancel": "取消"
1176
+ },
1177
+ "user": {
1178
+ "title": "用户管理",
1179
+ "create": "新建用户"
1180
+ }
1181
+ }
1182
+ ```
1183
+
1184
+ ### 使用原则
1185
+
1186
+ - 界面文案必须从 `locales` 取,禁止硬编码
1187
+ - 中文与其他语言共用同一套 key,避免中英文混用
1188
+ - 业务术语保持一致,如"用户"统一用 `user`,不要混用 `member`
1189
+ - 复数、日期、货币优先使用 i18n 库提供的格式化能力
1190
+
1191
+ ## 常量管理
1192
+
1193
+ 常量统一放在 `src/constants/` 目录下,禁止散落在业务代码中。
1194
+
1195
+ ```text
1196
+ src/constants/
1197
+ ├── index.ts # 统一导出
1198
+ ├── api.ts # API 相关常量、枚举
1199
+ ├── status.ts # 业务状态枚举
1200
+ ├── storage.ts # localStorage key
1201
+ └── config.ts # 应用配置项
1202
+ ```
1203
+
1204
+ ### 命名规范
1205
+
1206
+ - 普通常量:`UPPER_SNAKE_CASE`
1207
+ - 枚举:`PascalCase`,成员 `UPPER_SNAKE_CASE`
1208
+ - 配置对象:`camelCase`
1209
+
1210
+ ```ts
1211
+ // src/constants/status.ts
1212
+ export enum OrderStatus {
1213
+ PENDING = 'pending',
1214
+ PAID = 'paid',
1215
+ SHIPPED = 'shipped',
1216
+ COMPLETED = 'completed',
1217
+ }
1218
+
1219
+ export const ORDER_STATUS_OPTIONS = [
1220
+ { label: '待支付', value: OrderStatus.PENDING },
1221
+ { label: '已支付', value: OrderStatus.PAID },
1222
+ ];
1223
+ ```
1224
+
1225
+ ## 性能策略
1226
+
1227
+ - 路由懒加载
1228
+ - 组件按需引入 UI 库
1229
+ - 图片、字体懒加载和压缩
1230
+ - 合理使用 `v-memo`、`computed`、`useMemo`
1231
+ - 大列表使用虚拟滚动
1232
+
1233
+ ## 输出要求
1234
+
1235
+ 1. 先明确项目规模和业务模块
1236
+ 2. 给出推荐目录结构
1237
+ 3. 说明每个模块的职责边界
1238
+ 4. 给出状态管理、路由、API 层设计建议
1239
+ 5. 最后给出 1-2 个关键技术决策的理由