cmpt-huitu-cli 1.0.13 → 1.0.15

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.
@@ -53,16 +53,16 @@ trigger: always_on
53
53
 
54
54
  - **Element Plus**: `^2.11.1`
55
55
  - **@element-plus/icons-vue**: `^2.3.2`
56
+ - **ECharts**: `^5.5.0` (通过 `cmpt-huitu-ui` 集成)
56
57
 
57
58
  ### 共享包
58
59
 
59
- - **cmpt-huitu-ui**: `^1.0.0` - UI 组件库
60
- - **cmpt-huitu-utils**: `^1.0.0` - 工具函数库
60
+ - **cmpt-huitu-ui**: `workspace:*` - UI 组件库
61
+ - **cmpt-huitu-utils**: `workspace:*` - 工具函数库
61
62
 
62
63
  ### 工具库
63
64
 
64
65
  - **axios**: `^1.11.0` - HTTP 客户端
65
- - **dayjs**: `^1.11.18` - 时间处理
66
66
  - **lodash-es**: `^4.17.21` - 工具函数
67
67
  - **nprogress**: `^0.2.0` - 进度条
68
68
 
@@ -166,24 +166,25 @@ trigger: always_on
166
166
 
167
167
  - **会被 Vite 处理**,支持导入和路径别名
168
168
  - 存放会被代码引用的资源(图片、字体等)
169
- - 支持动态导入和路径别名 `@/assets/...`
169
+ - 支持动态导入和路径别名 `@assets/...`
170
170
 
171
171
  #### `src/routers/modules/` - 路由模块
172
172
 
173
173
  - **自动导入**:Vite 会自动扫描并合并所有 `.js` 文件
174
- - 每个模块导出一个路由对象或数组
174
+ - 每个模块导出一个路由对象数组 `export default [...]`
175
175
  - 文件名建议使用 `模块名.js` 格式
176
176
 
177
177
  #### `src/stores/` - 状态管理
178
178
 
179
179
  - 使用 Pinia,按模块组织
180
180
  - 每个模块一个文件,文件名即 store id
181
+ - 推荐使用 Options API 风格定义 Store (与模板保持一致),但也支持 Composition API
181
182
 
182
183
  #### `src/services/` - API 服务
183
184
 
184
185
  - 按功能模块组织 API 请求
185
186
  - 每个文件对应一个业务模块
186
- - 统一使用 `@/utils/requestAxios.js` 封装的 axios 实例
187
+ - 统一使用 `@utils/requestAxios.js` 封装的 axios 实例
187
188
 
188
189
  ---
189
190
 
@@ -207,31 +208,10 @@ trigger: always_on
207
208
  </script>
208
209
  ```
209
210
 
210
- #### 1.1 组件文件命名
211
+ #### 2. 组件命名
211
212
 
212
213
  - **组件文件名**:使用 **camelCase(小驼峰)**,如 `userProfile.vue`、`home.vue`
213
- - **组件注册名**:在模板中使用时,保持 camelCase 或转换为 PascalCase(Vue 会自动处理)
214
-
215
- #### 2. 编译器宏无需导入
216
-
217
- ```vue
218
- <script setup>
219
- // ✅ 正确:defineProps、defineEmits 是编译器宏,无需导入
220
- const props = defineProps({
221
- title: String,
222
- })
223
-
224
- const emit = defineEmits(['update'])
225
-
226
- // ❌ 错误:不要导入编译器宏
227
- // import { defineProps, defineEmits } from 'vue'
228
- </script>
229
- ```
230
-
231
- #### 3. 组件命名
232
-
233
- - **组件文件名**:使用 **camelCase(小驼峰)**,如 `userProfile.vue`、`home.vue`
234
- - **组件注册名**:在模板中使用时,Vue 会自动处理大小写转换(camelCase ↔ PascalCase)
214
+ - **组件注册名**:在模板中使用时,Vue 会自动处理大小写转换
235
215
  - **Props 定义**:使用对象形式,提供类型和默认值
236
216
 
237
217
  ```vue
@@ -250,7 +230,7 @@ trigger: always_on
250
230
  </script>
251
231
  ```
252
232
 
253
- #### 4. 样式规范
233
+ #### 3. 样式规范
254
234
 
255
235
  - **使用 Scoped 样式**:避免样式污染
256
236
  - **使用 CSS 变量**:利用主题系统
@@ -270,34 +250,31 @@ trigger: always_on
270
250
 
271
251
  #### 1. 路由模块化
272
252
 
273
- 在 `src/routers/modules/` 下创建路由模块:
253
+ 在 `src/routers/modules/` 下创建路由模块,**必须导出数组**:
274
254
 
275
255
  ```javascript
276
256
  // src/routers/modules/user.js
277
- export default {
278
- path: '/user',
279
- name: 'User',
280
- component: () => import('@/views/user/index.vue'),
281
- meta: {
282
- title: '用户管理',
283
- requiresAuth: true, // 需要登录
284
- },
285
- children: [
286
- {
287
- path: 'list',
288
- name: 'UserList',
289
- component: () => import('@/views/user/list.vue'),
257
+ export default [
258
+ {
259
+ path: '/user',
260
+ name: 'User',
261
+ component: () => import('@views/user/index.vue'),
262
+ meta: {
263
+ title: '用户管理',
264
+ requiresAuth: true, // 需要登录
290
265
  },
291
- ],
292
- }
266
+ children: [
267
+ {
268
+ path: 'list',
269
+ name: 'UserList',
270
+ component: () => import('@views/user/list.vue'),
271
+ },
272
+ ],
273
+ },
274
+ ]
293
275
  ```
294
276
 
295
- #### 2. 路由命名
296
-
297
- - **路由 name**:使用 PascalCase,与组件名对应
298
- - **路由 path**:使用 kebab-case,与菜单路径对应
299
-
300
- #### 3. 路由元信息
277
+ #### 2. 路由元信息
301
278
 
302
279
  使用 `meta` 字段存储路由元信息:
303
280
 
@@ -306,7 +283,6 @@ export default {
306
283
  meta: {
307
284
  title: '页面标题', // 页面标题
308
285
  requiresAuth: true, // 是否需要登录
309
- roles: ['admin'], // 权限角色
310
286
  keepAlive: true, // 是否缓存
311
287
  hidden: false, // 是否在菜单中隐藏
312
288
  },
@@ -317,38 +293,26 @@ export default {
317
293
 
318
294
  #### 1. Store 定义
319
295
 
320
- 使用 `defineStore` 定义 store
296
+ 使用 `defineStore` 定义 store,模板默认使用 Options API 风格:
321
297
 
322
298
  ```javascript
323
- // src/stores/user.js
299
+ // src/stores/index/global.js
324
300
  import { defineStore } from 'pinia'
325
- import { ref, computed } from 'vue'
326
-
327
- export const useUserStore = defineStore('user', () => {
328
- // State
329
- const userInfo = ref(null)
330
- const token = ref('')
331
301
 
332
- // Getters
333
- const isLoggedIn = computed(() => !!token.value)
334
-
335
- // Actions
336
- function setUserInfo(info) {
337
- userInfo.value = info
338
- }
302
+ export const globalStore = defineStore('global', {
303
+ state: () => ({
304
+ themeVal: 'light',
305
+ isLoading: false,
306
+ }),
339
307
 
340
- function logout() {
341
- userInfo.value = null
342
- token.value = ''
343
- }
344
-
345
- return {
346
- userInfo,
347
- token,
348
- isLoggedIn,
349
- setUserInfo,
350
- logout,
351
- }
308
+ actions: {
309
+ changeGlobalTheme(theme) {
310
+ this.themeVal = theme
311
+ },
312
+ setIsLoadingStore(status) {
313
+ this.isLoading = status
314
+ },
315
+ },
352
316
  })
353
317
  ```
354
318
 
@@ -358,20 +322,17 @@ export const useUserStore = defineStore('user', () => {
358
322
 
359
323
  ```vue
360
324
  <script setup>
361
- import { useUserStore } from '@/stores/user'
325
+ import { globalStore } from '@/stores/index/global'
326
+ import { storeToRefs } from 'pinia'
362
327
 
363
- const userStore = useUserStore()
328
+ // 1. 实例化 Store
329
+ const store = globalStore()
364
330
 
365
- // 访问 state
366
- console.log(userStore.userInfo)
331
+ // 2. 解构 state 需要使用 storeToRefs 保持响应式
332
+ const { themeVal } = storeToRefs(store)
367
333
 
368
- // 调用 action
369
- userStore.setUserInfo({ name: 'John' })
370
-
371
- // 使用 getter
372
- if (userStore.isLoggedIn) {
373
- // ...
374
- }
334
+ // 3. 解构 actions 可以直接使用
335
+ const { changeGlobalTheme } = store
375
336
  </script>
376
337
  ```
377
338
 
@@ -381,7 +342,7 @@ export const useUserStore = defineStore('user', () => {
381
342
 
382
343
  ```javascript
383
344
  // src/services/user.js
384
- import request from '@/utils/requestAxios'
345
+ import { axiosInstance as request } from '@/utils/requestAxios'
385
346
 
386
347
  // ✅ 推荐:统一使用封装的 request
387
348
  export function getUserList(params) {
@@ -401,24 +362,15 @@ export function createUser(data) {
401
362
  }
402
363
  ```
403
364
 
404
- #### 2. 在组件中使用
365
+ #### 2. 依赖注入 (可选)
405
366
 
406
- ```vue
407
- <script setup>
408
- import { ref, onMounted } from 'vue'
409
- import { getUserList } from '@/services/user'
410
-
411
- const list = ref([])
412
-
413
- onMounted(async () => {
414
- try {
415
- const res = await getUserList({ page: 1 })
416
- list.value = res.data
417
- } catch (error) {
418
- console.error('获取用户列表失败', error)
419
- }
420
- })
421
- </script>
367
+ 在某些场景(如通用组件库)中,可以使用依赖注入获取 request 实例:
368
+
369
+ ```javascript
370
+ import { getCurrentInstance } from 'vue'
371
+
372
+ const { proxy } = getCurrentInstance()
373
+ // proxy.$request 也是可用的
422
374
  ```
423
375
 
424
376
  ---
@@ -435,19 +387,13 @@ export function createUser(data) {
435
387
  | **工具函数** | camelCase | `formatDate.js` |
436
388
  | **常量文件** | UPPER_SNAKE_CASE | `ERROR_CODE.js` |
437
389
 
438
- ### 变量命名
439
-
440
- - **变量/函数**:camelCase - `userName`, `getUserInfo()`
441
- - **常量**:UPPER_SNAKE_CASE - `API_BASE_URL`, `MAX_COUNT`
442
- - **组件名**:PascalCase - `UserProfile`, `DataTable`
443
- - **CSS 类名**:kebab-case - `.user-profile`, `.data-table`
444
-
445
390
  ### 路径别名
446
391
 
447
- 使用 `jsconfig.json` 中定义的路径别名:
392
+ 使用 `vite.config.js` 中定义的路径别名:
448
393
 
449
394
  | 别名 | 对应路径 | 用途 |
450
395
  | -------------- | ----------------- | ------------ |
396
+ | `~/` | `./` | 项目根目录 |
451
397
  | `@/` | `src/` | 源代码根目录 |
452
398
  | `@public/` | `public/` | 静态资源目录 |
453
399
  | `@components/` | `src/components/` | 全局组件 |
@@ -458,16 +404,7 @@ export function createUser(data) {
458
404
  | `@utils/` | `src/utils/` | 工具函数 |
459
405
  | `@assets/` | `src/assets/` | 资源文件 |
460
406
  | `@services/` | `src/services/` | API 服务 |
461
-
462
- ```javascript
463
- // ✅ 推荐:使用路径别名(组件文件名使用 camelCase)
464
- import { parseTime } from '@/utils'
465
- import UserList from '@/views/user/list.vue'
466
- import { useUserStore } from '@/stores/user'
467
-
468
- // ❌ 不推荐:使用相对路径
469
- import { parseTime } from '../../utils'
470
- ```
407
+ | `@plugins/` | `src/plugins/` | 插件配置 |
471
408
 
472
409
  ---
473
410
 
@@ -490,7 +427,6 @@ const config = {
490
427
 
491
428
  // 文件服务配置
492
429
  uploadUrl: origin + '/upload',
493
- downloadUrl: origin + '/download',
494
430
 
495
431
  // ... 其他配置
496
432
  }
@@ -505,85 +441,17 @@ const config = {
505
441
  VITE_PORT=3001
506
442
  VITE_PATH=/
507
443
  VITE_MOCK=true
508
-
509
- # .env.production
510
- VITE_PATH=/production-path/
511
- VITE_MOCK=false
512
- ```
513
-
514
- 在代码中使用:
515
-
516
- ```javascript
517
- // ✅ 正确:使用 import.meta.env
518
- const apiUrl = import.meta.env.VITE_API_URL
519
-
520
- // ❌ 错误:不要使用 process.env(Vite 不支持)
521
- // const apiUrl = process.env.VITE_API_URL
522
- ```
523
-
524
- ### Vite 配置
525
-
526
- 主要配置在 `vite.config.js`,已预配置:
527
-
528
- - **路径别名**:`@/`、`@public/` 等
529
- - **自动导入**:Vue API、组件、Element Plus 组件
530
- - **SCSS 全局变量**:自动注入 `cmpt-huitu-ui` 样式变量
531
- - **代理配置**:开发环境 API 代理
532
- - **构建优化**:代码分割、压缩等
533
-
534
- ---
535
-
536
- ## 💻 开发规范
537
-
538
- ### 1. 开发流程
539
-
540
- ```bash
541
- # 1. 安装依赖
542
- pnpm install
543
-
544
- # 2. 启动开发服务器
545
- pnpm dev
546
-
547
- # 3. 代码检查
548
- pnpm lint
549
-
550
- # 4. 构建生产版本
551
- pnpm build
552
-
553
- # 5. 预览构建结果
554
- pnpm preview
555
444
  ```
556
445
 
557
- ### 2. Git 提交规范
446
+ ### ECharts 引入规范
558
447
 
559
- 遵循 [Conventional Commits](https://www.conventionalcommits.org/) 规范:
560
-
561
- ```bash
562
- # 功能新增
563
- git commit -m "feat: 添加用户管理页面"
448
+ **允许全量引入**:为了避免构建时的 `install` 导出警告,并简化开发,本项目允许直接全量引入 ECharts。
564
449
 
565
- # 问题修复
566
- git commit -m "fix: 修复登录后跳转错误"
567
-
568
- # 文档更新
569
- git commit -m "docs: 更新 README"
570
-
571
- # 代码重构
572
- git commit -m "refactor: 重构用户服务代码"
573
-
574
- # 样式调整
575
- git commit -m "style: 调整页面布局"
450
+ ```javascript
451
+ // packages/ui/index.js
452
+ import * as echarts from 'echarts'
576
453
  ```
577
454
 
578
- ### 3. 代码审查要点
579
-
580
- - ✅ 是否遵循命名规范
581
- - ✅ 是否使用路径别名而非相对路径
582
- - ✅ 是否正确处理异步操作(try-catch)
583
- - ✅ 是否使用共享包而非重复实现
584
- - ✅ 样式是否使用 scoped 或 CSS 变量
585
- - ✅ 是否移除未使用的导入和代码
586
-
587
455
  ---
588
456
 
589
457
  ## ✨ 最佳实践
@@ -594,13 +462,10 @@ git commit -m "style: 调整页面布局"
594
462
 
595
463
  ```javascript
596
464
  // ✅ 推荐:使用共享工具函数
597
- import { parseTime, cache, modal } from 'cmpt-huitu-utils'
465
+ import { cache } from 'cmpt-huitu-utils'
598
466
 
599
467
  // ✅ 推荐:使用共享 UI 组件
600
- import { HTable, VexTable, HtDialog } from 'cmpt-huitu-ui'
601
-
602
- // ❌ 不推荐:重复实现已有功能
603
- // function formatTime(time) { ... } // 已有 parseTime
468
+ import { HTable, VexTable } from 'cmpt-huitu-ui'
604
469
  ```
605
470
 
606
471
  ### 2. 组件复用
@@ -614,40 +479,20 @@ import { HTable, VexTable, HtDialog } from 'cmpt-huitu-ui'
614
479
  - 使用路由懒加载
615
480
  - 大组件使用异步组件
616
481
  - 合理使用 `v-memo` 和 `v-once`
617
- - 图片使用懒加载
618
-
619
- ```javascript
620
- // ✅ 路由懒加载(文件名使用 camelCase)
621
- component: () => import('@/views/user/index.vue')
622
-
623
- // ✅ 异步组件(文件名使用 camelCase)
624
- const AsyncComponent = defineAsyncComponent(() => import('@/components/heavyComponent.vue'))
625
- ```
626
482
 
627
483
  ### 4. 错误处理
628
484
 
629
485
  统一错误处理:
630
486
 
631
487
  ```javascript
632
- // ✅ 推荐:统一错误处理
633
488
  try {
634
489
  const res = await getUserList()
635
- // 处理成功
636
490
  } catch (error) {
637
491
  console.error('获取用户列表失败', error)
638
- ElMessage.error('获取用户列表失败,请稍后重试')
492
+ // requestAxios 已有统一的错误拦截提示,通常无需再次弹窗
639
493
  }
640
494
  ```
641
495
 
642
- ### 5. 类型安全
643
-
644
- 利用自动生成的类型文件:
645
-
646
- ```typescript
647
- // components.d.ts 和 imports.d.ts 由插件自动生成
648
- // 提供完整的类型提示
649
- ```
650
-
651
496
  ---
652
497
 
653
498
  ## ⚠️ 注意事项
@@ -657,37 +502,26 @@ try {
657
502
  - ✅ **`public/config/envCfg.js`** - 环境配置(API 地址、登录配置等)
658
503
  - ✅ **`index.html`** - 页面标题、项目名称
659
504
  - ✅ **`package.json`** - 项目名称、描述(CLI 会自动修改)
660
- - ✅ **`vite.config.js`** - 如需自定义构建配置
661
505
 
662
506
  ### 2. 共享包依赖
663
507
 
664
508
  - ✅ 使用 `workspace:*` 在 Monorepo 中开发
665
- - ✅ CLI 创建项目时自动转换为版本号(如 `^1.0.0`)
509
+ - ✅ CLI 创建项目时自动转换为版本号
666
510
  - ✅ 不要手动修改 `package.json` 中的共享包版本
667
511
 
668
512
  ### 3. 样式变量
669
513
 
670
- - ✅ 使用 `cmpt-huitu-ui` 提供的全局 SCSS 变量
514
+ - ✅ 自动注入了 `cmpt-huitu-ui` 的全局 SCSS 变量(在 vite.config.js 中配置)
671
515
  - ✅ 自定义主题变量放在 `src/styles/theme/variables.scss`
672
- - ✅ 使用 `@use` 替代 `@import`(避免弃用警告)
673
516
 
674
517
  ### 4. 路由模块
675
518
 
676
- - ✅ 路由模块自动导入,无需手动注册
519
+ - ✅ 路由模块自动导入,**必需导出数组**
677
520
  - ✅ 404 路由会自动添加到最后
678
- - ✅ 路由守卫在 `src/routers/guard.js` 中统一处理
679
-
680
- ### 5. 环境变量
681
521
 
682
- - 只在 `.env` 文件中使用,不要提交到 Git
683
- - ✅ 使用 `VITE_` 前缀
684
- - ✅ 在代码中使用 `import.meta.env.VITE_XXX`
522
+ ### 5. 跨平台兼容性
685
523
 
686
- ### 6. 构建优化
687
-
688
- - ✅ 生产构建会自动压缩和优化
689
- - ✅ 使用 `pnpm preview` 预览生产构建结果
690
- - ✅ 构建产物在 `dist/` 目录
524
+ - ✅ **禁止**在 `package.json` 的 `dependencies` 中硬编码平台特定依赖(如 `@esbuild/darwin-arm64`),这会导致 Windows 环境安装失败。
691
525
 
692
526
  ---
693
527
 
@@ -701,15 +535,4 @@ try {
701
535
 
702
536
  ---
703
537
 
704
- ## 🔄 更新日志
705
-
706
- - **v1.0.0** (2026-01-04)
707
- - 初始版本
708
- - 集成 Vue 3 + Vite + Element Plus
709
- - 集成 cmpt-huitu-ui 和 cmpt-huitu-utils
710
- - 完整的开发规范和最佳实践
711
-
712
- ---
713
-
714
- **维护者**: 慧图前端团队
715
- **最后更新**: 2026-01-04
538
+ **最后更新**: 2026-01-14