165 Commits

Author SHA1 Message Date
fd32fdaaeb chore(deps): update all non-major dependencies
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Failing after 2m11s
CI/CD Pipeline / build-and-deploy (push) Has been skipped
2026-01-28 20:04:56 +08:00
17730cfb10 chore(deps): update dependency @pinia/colada to ^0.21.0
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m10s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m50s
测试最新依赖 / playwright (push) Failing after 1m54s
测试最新依赖 / build-and-test (push) Failing after 2m10s
2026-01-21 00:26:04 +08:00
c4b93140f0 chore(deps): update dependency vite to v7.3.1
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m9s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m13s
测试最新依赖 / build-and-test (push) Failing after 1m29s
测试最新依赖 / playwright (push) Successful in 2m23s
2026-01-10 16:06:22 +08:00
1a9257249f chore(deps): update dependency @pinia/colada to ^0.20.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m7s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m5s
测试最新依赖 / build-and-test (push) Successful in 1m32s
测试最新依赖 / playwright (push) Successful in 1m57s
2026-01-07 01:48:38 +08:00
严浩
66280dc6a1 chore(devcontainer): remove AI setup configurations
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m55s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m55s
测试最新依赖 / build-and-test (push) Successful in 1m44s
测试最新依赖 / playwright (push) Successful in 1m49s
2026-01-04 23:31:37 +08:00
16c93a82a2 chore(deps): replace dependency @tsconfig/node22 with @tsconfig/node24
Some checks are pending
renovate/stability-days Updates have not met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m50s
测试最新依赖 / build-and-test (push) Successful in 1m28s
测试最新依赖 / playwright (push) Successful in 1m53s
2026-01-02 01:06:25 +08:00
16d4b3f749 chore(deps): update primevue pkgs to v4.5.4
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m38s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m57s
测试最新依赖 / build-and-test (push) Successful in 1m43s
测试最新依赖 / playwright (push) Successful in 1m54s
2026-01-01 22:28:04 +08:00
42f63f7134 chore(deps): update dependency unplugin-vue-router to v0.19.2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m7s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m51s
2026-01-01 19:08:32 +08:00
9d12927793 chore(deps): update dependency @pinia/colada to ^0.19.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m59s
测试最新依赖 / playwright (push) Successful in 1m59s
测试最新依赖 / build-and-test (push) Successful in 2m7s
2025-12-31 06:25:53 +08:00
bb82a6ab83 chore(deps): update dependency @vitejs/plugin-vue-jsx to v5.1.3
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m53s
测试最新依赖 / playwright (push) Successful in 1m41s
测试最新依赖 / build-and-test (push) Successful in 1m51s
2025-12-27 12:15:40 +08:00
76d2a45015 chore(deps): update primevue pkgs to v4.5.3
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m10s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m57s
测试最新依赖 / playwright (push) Failing after 1m2s
测试最新依赖 / build-and-test (push) Failing after 1m28s
2025-12-24 23:32:51 +08:00
严浩
935251ee53 chore(devcontainer): update configuration and lifecycle scripts
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m43s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m14s
测试最新依赖 / playwright (push) Successful in 1m46s
测试最新依赖 / build-and-test (push) Successful in 2m6s
2025-12-24 00:19:05 +08:00
5472f1c9b9 chore(deps): update dependency eslint-plugin-perfectionist to v5
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m49s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m51s
测试最新依赖 / build-and-test (push) Successful in 1m54s
测试最新依赖 / playwright (push) Successful in 1m58s
2025-12-23 01:06:20 +08:00
744703811a chore(deps): update primevue pkgs to v4.5.2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m38s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m53s
2025-12-22 19:25:58 +08:00
be3d59691b chore(deps): update dependency primelocale to v2.2.3
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m38s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m47s
测试最新依赖 / build-and-test (push) Successful in 1m35s
测试最新依赖 / playwright (push) Successful in 1m46s
2025-12-19 04:51:01 +08:00
f6bccd7536 chore(deps): update dependency unplugin-vue-router to v0.19.1
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m45s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m46s
测试最新依赖 / build-and-test (push) Successful in 1m59s
测试最新依赖 / playwright (push) Successful in 2m28s
2025-12-18 23:35:22 +08:00
4673d622b6 chore(deps): update dependency vite to v7.3.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m18s
2025-12-18 20:56:11 +08:00
0e467a1e9d chore(deps): update primevue pkgs to v4.5.1
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m44s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m15s
测试最新依赖 / build-and-test (push) Successful in 1m28s
测试最新依赖 / playwright (push) Successful in 2m16s
2025-12-17 23:51:43 +08:00
7a5610c0dc chore(deps): update all non-major dependencies
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m35s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m51s
测试最新依赖 / playwright (push) Successful in 1m42s
测试最新依赖 / build-and-test (push) Successful in 2m9s
2025-12-17 03:32:37 +08:00
80d989f6d0 chore(deps): update dependency @pinia/colada to ^0.18.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m49s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m54s
2025-12-17 00:53:21 +08:00
6097d39752 chore(deps): update dependency @primeuix/themes to v2
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m28s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m57s
2025-12-16 23:17:01 +08:00
4bc62221b6 chore(deps): update dependency @vitejs/plugin-vue to v6.0.3
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m37s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m54s
测试最新依赖 / build-and-test (push) Successful in 1m33s
测试最新依赖 / playwright (push) Successful in 2m22s
2025-12-15 17:45:16 +08:00
c405bc9481 chore(deps): update dependency @intlify/unplugin-vue-i18n to v11.0.3
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m44s
测试最新依赖 / build-and-test (push) Successful in 1m44s
测试最新依赖 / playwright (push) Successful in 2m22s
2025-12-14 21:56:20 +08:00
54cc46b33a chore(deps): update all non-major dependencies
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m36s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m58s
测试最新依赖 / build-and-test (push) Successful in 1m29s
测试最新依赖 / playwright (push) Successful in 2m26s
2025-12-12 23:14:48 +08:00
65ee7cccb3 chore(deps): update dependency happy-dom to v20.0.11
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m45s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m12s
2025-12-12 09:52:28 +08:00
6da6e59b6d chore(deps): update primevue pkgs to v4.5.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m10s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m54s
2025-12-12 03:56:01 +08:00
8e6d7488f4 chore(deps): update dependency vite-plugin-checker to ^0.12.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m5s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m55s
测试最新依赖 / build-and-test (push) Successful in 1m32s
测试最新依赖 / playwright (push) Successful in 2m22s
2025-12-12 01:36:17 +08:00
严浩
9e050306bb feat: refactor Vite plugin loading mechanism and improve plugin management
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m3s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m6s
2025-12-12 00:09:53 +08:00
7f1811098f 更新 .github/workflows/测试最新依赖.yaml
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m37s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m46s
2025-12-11 21:04:48 +08:00
40b3686f2e chore(deps): update dependency @playwright/test to v1.57.0
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
CI/CD Pipeline / playwright (push) Has been cancelled
2025-12-11 21:03:49 +08:00
dfc64ecece 更新 .github/workflows/ci-cd.yaml
Some checks failed
CI/CD Pipeline / playwright (push) Failing after 2m0s
CI/CD Pipeline / build-and-deploy (push) Has been skipped
2025-12-11 20:58:32 +08:00
1df5110034 chore(deps): update dependency @prettier/plugin-oxc to ^0.1.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m36s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m55s
2025-12-11 17:44:41 +08:00
731a3da55d chore(deps): update dependency @vueuse/core to v14.1.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m48s
2025-12-11 15:08:52 +08:00
4e5b3cb96c chore(deps): update dependency vite to v7.2.7
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m44s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m56s
2025-12-11 11:47:59 +08:00
5e8df2572f chore(deps): update dependency @cloudflare/vite-plugin to v1.15.3
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m5s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m47s
测试最新依赖 / build-and-test (push) Successful in 1m41s
测试最新依赖 / playwright (push) Failing after 2m12s
2025-12-11 01:01:20 +08:00
严浩
7d6474c92b refactor: update loadPlugin to use async/await and improve vueRouter configuration
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m44s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m40s
2025-12-11 00:05:04 +08:00
严浩
86920da611 refactor: update component names to PascalCase and improve structure
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m17s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m50s
- Changed component names from kebab-case to PascalCase in various files for consistency.
- Updated `<router-view>` and `<transition>` to `<RouterView>` and `<Transition>` respectively in App.vue and base-layout.vue.
- Refactored AppNaiveUIProvider.vue to use PascalCase for Naive UI providers.
- Adjusted language and theme switch buttons to use PascalCase for icon components.
- Updated button components in demo pages to use PascalCase for Naive UI buttons.
- Modified ESLint rules in route message files to use perfectionist/sort-objects for better key sorting.
- Enhanced Vite plugin files to export loadPlugin functions for better plugin management.
- Improved plugin loading logic to handle errors and warnings more effectively.
2025-12-10 22:52:23 +08:00
3828f12a2d chore(deps): update dependency vue-i18n to v11.2.2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m50s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m55s
2025-12-10 14:06:40 +08:00
f269a25968 chore(deps): update dependency vitest to v4.0.14
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m1s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m41s
测试最新依赖 / playwright (push) Failing after 1m58s
测试最新依赖 / build-and-test (push) Successful in 2m12s
2025-12-09 23:45:38 +08:00
4a97eca056 chore(deps): update yanhao98/composite-actions digest to faab20a
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m5s
2025-12-09 07:24:47 +08:00
e91476f55c chore(deps): update dependency @pinia/colada to v0.17.9
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m41s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m2s
测试最新依赖 / build-and-test (push) Failing after 2m3s
测试最新依赖 / playwright (push) Failing after 2m25s
2025-12-08 20:33:22 +08:00
afd08f05fc chore(deps): update dependency @iconify-json/material-symbols to v1.2.48
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m50s
2025-12-08 15:17:29 +08:00
b2f9b9d3b3 chore(deps): update dependency unplugin-vue-router to ^0.19.0
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m3s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m46s
测试最新依赖 / playwright (push) Failing after 1m47s
测试最新依赖 / build-and-test (push) Failing after 1m56s
2025-12-08 03:37:20 +08:00
严浩
9cb70b7827 chore: remove unused h-setup-ai-tools command and update vue-devtools plugin logic
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m1s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m49s
2025-12-07 16:38:52 +08:00
52b1e4fb6b chore(deps): update all non-major dependencies to v3.1.5
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m48s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m40s
2025-12-07 05:42:51 +08:00
f101237792 chore(deps): update dependency vite to v7.2.6
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m41s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m49s
测试最新依赖 / build-and-test (push) Successful in 1m36s
测试最新依赖 / playwright (push) Failing after 2m10s
2025-12-04 15:17:40 +08:00
c84380836a chore(deps): update dependency unplugin-vue-router to ^0.18.0
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m37s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m7s
测试最新依赖 / playwright (push) Failing after 1m39s
测试最新依赖 / build-and-test (push) Successful in 2m16s
2025-12-01 21:04:41 +08:00
aca2c29946 chore(deps): update dependency unplugin-vue-router to v0.17.2
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m52s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m39s
测试最新依赖 / build-and-test (push) Successful in 1m35s
测试最新依赖 / playwright (push) Failing after 2m29s
2025-12-01 02:12:49 +08:00
9d1374d53c chore(deps): update dependency unplugin-auto-import to v20.3.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m42s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m49s
2025-11-30 12:22:47 +08:00
严浩
814130af34 refactor: devcontainer
Some checks failed
CI/CD Pipeline / playwright (push) Successful in 2m40s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m55s
测试最新依赖 / build-and-test (push) Successful in 1m30s
测试最新依赖 / playwright (push) Failing after 2m12s
2025-11-23 00:00:26 +08:00
4a5ae8d2de chore(deps): update vite packages
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m53s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m51s
2025-11-22 10:52:13 +08:00
18fd9cb226 chore(deps): update dependency rollup to v4.53.1
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m51s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m46s
2025-11-22 06:03:12 +08:00
188c813447 chore(deps): update all non-major dependencies
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m6s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m11s
测试最新依赖 / playwright (push) Successful in 2m5s
测试最新依赖 / build-and-test (push) Successful in 2m9s
2025-11-22 00:48:21 +08:00
737da9c585 chore(deps): update dependency @pinia/colada to v0.17.8
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m35s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m5s
2025-11-21 19:01:10 +08:00
80090fdb90 chore(deps): update dependency @cloudflare/vite-plugin to v1.14.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m36s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m51s
2025-11-21 06:43:22 +08:00
abcf706acc chore(deps): update dependency vite-plugin-vue-devtools to v8.0.5
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m56s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m4s
2025-11-21 03:52:52 +08:00
760b75083d chore(deps): update dependency sharp to v0.34.5
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m35s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m49s
测试最新依赖 / build-and-test (push) Successful in 1m32s
测试最新依赖 / playwright (push) Successful in 2m7s
2025-11-20 23:58:52 +08:00
0b4575b181 chore(deps): update dependency pinia to v3.0.4
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m58s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m52s
测试最新依赖 / build-and-test (push) Successful in 1m48s
测试最新依赖 / playwright (push) Successful in 1m51s
2025-11-19 18:59:22 +08:00
57fb6d5256 chore(deps): update dependency unplugin-vue-router to ^0.17.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m40s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m51s
测试最新依赖 / playwright (push) Successful in 1m38s
测试最新依赖 / build-and-test (push) Successful in 1m48s
2025-11-19 01:15:14 +08:00
e516dd4ba6 chore(deps): update dependency @cloudflare/vite-plugin to v1.13.19
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m7s
2025-11-18 22:50:15 +08:00
6fc619315a chore(deps): update dependency vite-plugin-fake-server to v2.2.2
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m38s
CI/CD Pipeline / build-and-deploy (push) Failing after 2m21s
2025-11-18 20:01:02 +08:00
a5082ef4e4 chore(deps): update dependency unplugin-vue-router to v0.16.2
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m35s
CI/CD Pipeline / build-and-deploy (push) Failing after 1m49s
2025-11-18 17:31:38 +08:00
9be884be20 chore(deps): update dependency @pinia/colada to v0.17.7
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m57s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m5s
2025-11-18 14:33:36 +08:00
Yanhao-MBP
bbec2a3ff9 refactor(devcontainer): 合并配置脚本为单一环境设置脚本
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m48s
2025-11-18 13:41:14 +08:00
Yanhao
aa851bb920 chore(devcontainer): update image tag to main in devcontainer configuration
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m34s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m58s
2025-11-18 10:48:41 +08:00
Yanhao
5610d3ea20 fix(.gitignore): add .pnpm-store to ignore list 2025-11-18 10:43:15 +08:00
7a20a45035 chore(deps): update yanhao98/composite-actions digest to 94776ed
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m49s
2025-11-18 06:58:54 +08:00
db3f77d6d3 chore(deps): update all non-major dependencies to v3.1.3
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m36s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m47s
2025-11-18 03:39:30 +08:00
严浩
e6731afff5 chore: update devcontainer configuration and add setup scripts
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m53s
测试最新依赖 / build-and-test (push) Successful in 1m31s
测试最新依赖 / playwright (push) Successful in 2m26s
2025-11-18 00:47:42 +08:00
3affb21d99 chore(deps): update all non-major dependencies
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m59s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m47s
测试最新依赖 / playwright (push) Successful in 1m50s
测试最新依赖 / build-and-test (push) Successful in 2m6s
2025-11-15 17:32:55 +08:00
严浩
2585b70f6b fix(Dockerfile): comment out VS Code shell integration line in zsh configuration
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m59s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m53s
2025-11-15 16:20:56 +08:00
严浩
a4e162cab0 build(devcontainer): configure pnpm cache and workspace settings
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m34s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m43s
测试最新依赖 / playwright (push) Successful in 1m49s
测试最新依赖 / build-and-test (push) Successful in 1m55s
2025-11-13 23:14:49 +08:00
严浩
88cc365935 build(devcontainer): adjust pnpm store directory creation 2025-11-13 22:51:55 +08:00
严浩
33801ca211 style(eslint): enforce padding between blocks in vue components
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m34s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m56s
2025-11-13 22:16:40 +08:00
严浩
4f79426206 build(devcontainer): 添加 VS Code shell 集成配置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m51s
2025-11-13 13:52:38 +08:00
严浩
1185843982 feat(.devcontainer): 调整 VS Code 扩展配置与 Copilot 相关设置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m39s
2025-11-13 13:37:04 +08:00
0620651b12 chore(deps): update all non-major dependencies
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m35s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m5s
测试最新依赖 / build-and-test (push) Successful in 1m48s
测试最新依赖 / playwright (push) Successful in 2m27s
2025-11-13 01:07:40 +08:00
严浩
a82190d4aa chore(devcontainer): configure chat tool auto-approval
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m55s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m45s
2025-11-13 00:27:35 +08:00
严浩
d0a7afd5df chore(devcontainer): refine configuration and simplify tasks
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m58s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m12s
2025-11-12 23:56:59 +08:00
严浩
10fcb40d1d docs: 更新开发服务器部分,添加关于 Playwright 测试的说明
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m45s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m50s
2025-11-12 22:37:44 +08:00
严浩
c7dccb0664 build(tooling): configure pnpm workspaces and update dev tooling
Some checks failed
CI/CD Pipeline / playwright (push) Failing after 1m13s
CI/CD Pipeline / build-and-deploy (push) Has been skipped
2025-11-12 14:17:15 +08:00
严浩
1bcecabf7b chore(devcontainer): add todo-tree vscode extension
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m55s
2025-11-12 11:31:45 +08:00
严浩
b7b508af08 chore(devcontainer): add gcmp vscode extension
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
CI/CD Pipeline / playwright (push) Has been cancelled
2025-11-12 11:29:47 +08:00
严浩
917b3c7324 fix(devcontainer): 优化端口转发配置并添加 iflow 权限修复脚本
Some checks failed
CI/CD Pipeline / playwright (push) Successful in 1m39s
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
2025-11-12 11:19:07 +08:00
严浩
6a73a274bd chore(vscode): enable i18n-ally editing and configure json formatting
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m58s
2025-11-12 11:09:09 +08:00
严浩
82897ea690 build(devcontainer): add iflow-cli support
Some checks failed
CI/CD Pipeline / playwright (push) Successful in 1m45s
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
2025-11-12 11:05:57 +08:00
严浩
e04310c2c9 style(devcontainer): format JSON configuration and add reference link 2025-11-12 11:05:57 +08:00
d2a21581ff chore(deps): update all non-major dependencies
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m32s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m50s
测试最新依赖 / build-and-test (push) Successful in 1m41s
测试最新依赖 / playwright (push) Successful in 1m52s
2025-11-11 16:39:11 +08:00
严浩
a2c49cf600 refactor: 删除 use-safe-n-form-auto-imports.tsx 文件
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m34s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m5s
2025-11-11 12:42:15 +08:00
严浩
3429c75600 build(devcontainer): 添加容器名称配置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m56s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m17s
测试最新依赖 / playwright (push) Successful in 1m59s
测试最新依赖 / build-and-test (push) Successful in 2m13s
2025-11-10 22:42:49 +08:00
0f57624cdf chore(deps): update dependency vite to v7.2.2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m59s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m2s
2025-11-10 18:35:56 +08:00
严浩
68fc6ad1a3 fix(i18n-auto-imports): 修复菜单翻译缺失时的提示信息
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m34s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m46s
2025-11-10 15:52:43 +08:00
严浩
b4727a1946 feat(devcontainer): 添加 antfu.unocss 插件支持
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m31s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m44s
2025-11-10 13:44:17 +08:00
严浩
f757b70174 build(devcontainer): use dynamic workspace folder name
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m39s
2025-11-10 12:53:33 +08:00
严浩
3033a8a707 build(devcontainer): 将PNPM环境变量从ARG改为ENV声明
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m58s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m8s
将Dockerfile中的PNPM_HOME和PATH从构建参数(ARG)改为环境变量(ENV)声明,
确保在容器运行时这些变量仍然有效。
2025-11-10 11:23:43 +08:00
严浩
fa77b772be build(devcontainer): 添加 host.docker.internal 作为主机网关
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m32s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m43s
2025-11-10 10:53:18 +08:00
严浩
2440605fce feat(vscode): 配置开发任务在文件夹打开时自动运行 [skip ci] 2025-11-10 00:46:18 +08:00
严浩
386b65cd05 Revert "fix(devcontainer): 修改 pnpm-store 卷挂载路径 [skip ci]"
This reverts commit b6fd7c698c.
2025-11-10 00:21:01 +08:00
严浩
b6fd7c698c fix(devcontainer): 修改 pnpm-store 卷挂载路径 [skip ci] 2025-11-10 00:11:14 +08:00
严浩
9376f8e68e feat(demos): 移除 Naive UI Demo 中的 SafeNForm 示例 [skip ci] 2025-11-10 00:07:22 +08:00
严浩
3a3e9aead5 docs(AGENTS.md): 移除关于 Naive UI 表单布局的冗余内容 2025-11-10 00:05:04 +08:00
严浩
97009158e8 refactor(scripts): 调整 all 脚本命令中任务执行顺序 [skip ci] 2025-11-10 00:04:34 +08:00
严浩
a9b916221c refactor(devcontainer): 调整 Dockerfile 和 devcontainer 配置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m46s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m44s
测试最新依赖 / build-and-test (push) Successful in 2m13s
测试最新依赖 / playwright (push) Successful in 2m31s
将 DEVCONTAINER 和 SANDBOX 环境变量从 Dockerfile 移至 devcontainer.json,
以提升配置的灵活性和一致性。同时,更新注释内容以准确反映当前安装脚本的功能。
2025-11-09 22:26:03 +08:00
严浩
ac7cb6a31c build(devcontainer): 调整 pnpm LTS 版本配置时机
将 `pnpm env use lts --global` 命令从 Dockerfile 和 postCreateCommand 中移除,
并在 devcontainer.json 的 onCreateCommand 阶段添加该命令

[skip ci]
2025-11-09 22:20:34 +08:00
严浩
fdf928028c chore(pnpm-workspace): 清理工作区配置文件
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m33s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m44s
移除不必要的包路径配置和注释项
2025-11-09 21:58:19 +08:00
严浩
3f31d188f6 build(devcontainer): 更新 pnpm 配置为全局设置存储目录 [skip ci] 2025-11-09 21:53:19 +08:00
c200206487 chore(deps): update dependency vite to v7.2.1
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m45s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m40s
2025-11-09 13:46:09 +08:00
严浩
b7aab0a6a5 build(devcontainer): 添加SANDBOX环境变量配置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m46s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m41s
测试最新依赖 / build-and-test (push) Successful in 1m47s
测试最新依赖 / playwright (push) Successful in 1m56s
2025-11-09 02:49:47 +08:00
严浩
37a0d59f13 docs(package.json): 更新 devEngines.runtime 文档链接位置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m34s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m42s
2025-11-09 02:28:26 +08:00
严浩
163af5e80c build(devcontainer): 优化 zsh 配置与 pnpm 环境设置
Some checks failed
CI/CD Pipeline / playwright (push) Failing after 1m58s
CI/CD Pipeline / build-and-deploy (push) Has been skipped
2025-11-09 00:55:03 +08:00
8e148c6408 chore(deps): update dependency vite to v7.2.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 1m43s
CI/CD Pipeline / build-and-deploy (push) Successful in 1m50s
2025-11-08 20:35:14 +08:00
严浩
1f78af72fc refactor(devcontainer): 修改开发容器名称
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 1m56s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m3s
2025-11-08 19:07:00 +08:00
169e0984a4 chore(deps): update yanhao98/composite-actions digest to 336b588
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m2s
2025-11-08 18:46:53 +08:00
严浩
be9093fa77 feat(devcontainer): 调整挂载卷命名并优化容器命令执行流程
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m20s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m38s
2025-11-08 17:14:23 +08:00
严浩
5a6fdc0efd feat: 更新 Dockerfile 和 devcontainer.json,修改工作目录路径为 /wrkspc
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m53s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m57s
2025-11-08 16:22:54 +08:00
7551eed484 chore(deps): update dependency vue-tsc to v3.1.2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m58s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m37s
2025-11-08 11:33:24 +08:00
严浩
a4068df0be feat: 更新 devcontainer.json,添加终端配置图标
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m22s
CI/CD Pipeline / build-and-deploy (push) Successful in 3m26s
测试最新依赖 / build-and-test (push) Successful in 1m40s
测试最新依赖 / playwright (push) Successful in 2m35s
2025-11-08 03:00:56 +08:00
严浩
ccf61ee6c3 feat: 更新 Dockerfile 和 devcontainer.json
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m25s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m32s
2025-11-08 02:51:05 +08:00
严浩
3170fe889b chore: 清理 .npmrc 文件,更新 pnpm-workspace.yaml 配置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m12s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m40s
2025-11-08 00:41:56 +08:00
严浩
aa55508ed7 feat: 更新 Dockerfile 和 devcontainer.json,添加别名和配置目录
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m11s
CI/CD Pipeline / build-and-deploy (push) Successful in 3m13s
2025-11-07 11:44:59 +00:00
严浩
8d052bcac8 feat: 更新 Dockerfile 和 devcontainer.json,优化开发环境配置和扩展推荐
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m17s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m26s
2025-11-07 08:18:45 +00:00
严浩
ce2f5338de feat: 更新 VSCode 扩展推荐列表,添加 stylelint 和 lokalise.i18n-ally 2025-11-07 02:11:50 +00:00
966c40a338 chore(deps): update dependency @cloudflare/vite-plugin to v1.13.15
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m14s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m27s
测试最新依赖 / build-and-test (push) Successful in 1m50s
测试最新依赖 / playwright (push) Successful in 2m47s
2025-11-07 03:23:09 +08:00
严浩
fd42a4d6d5 chore(devcontainer): update forwarded ports to 4730 and 4731
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m2s
CI/CD Pipeline / build-and-deploy (push) Successful in 3m13s
2025-11-06 17:43:14 +00:00
严浩
f883e0bec1 feat: 更新 pnpm 配置以设置全局存储目录 2025-11-07 01:38:48 +08:00
严浩
17bdbce8c8 feat: 添加 Dockerfile 和 devcontainer.json 文件以支持开发环境配置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m17s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m48s
2025-11-07 01:34:21 +08:00
严浩
61e86e731d chore(husky): 移除时间命令以简化 commit-msg、post-merge 和 pre-commit 钩子
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m1s
CI/CD Pipeline / build-and-deploy (push) Successful in 3m17s
2025-11-06 13:39:02 +08:00
严浩
ff790c7a3a feat: 添加 @intlify/eslint-plugin-vue-i18n 支持并更新相关配置
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
CI/CD Pipeline / playwright (push) Has been cancelled
2025-11-06 13:37:29 +08:00
076b8f3407 chore(deps): update dependency vitest to v4
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m14s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m48s
2025-11-06 00:46:19 +08:00
269d93187c chore(deps): update dependency @vueuse/core to v14
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 4m19s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m4s
测试最新依赖 / playwright (push) Successful in 2m24s
测试最新依赖 / build-and-test (push) Successful in 2m34s
2025-11-05 23:50:27 +08:00
33676dcc8b chore(deps): update dependency unplugin-vue-components to v30
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
CI/CD Pipeline / playwright (push) Has been cancelled
2025-11-05 23:50:18 +08:00
严浩
290aed74f2 fix(App): 调整 Toast 组件 z-index 并优化国际化缺失提示
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
CI/CD Pipeline / playwright (push) Has been cancelled
- 为 Toast 组件添加 style="z-index: 5000" 以确保其层级高于其他 UI 元素
- 在开发模式下,当菜单翻译缺失时,通过 ToastService 弹出警告提示
- 更新 app-config 插件中的 __DEV__ 注释,明确其来源于 vite.config.ts 的 define 配置
- 提高 PrimeVue 的 zIndex 配置值,避免与自定义组件层级冲突
2025-11-05 23:23:28 +08:00
严浩
fd0543dcc2 build(package.json): 调整脚本执行顺序并增强格式化与检查命令
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m45s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m3s
2025-11-05 23:09:08 +08:00
严浩
fcd840d4fe feat(primevue): 配置PrimeVue的zIndex和类型约束
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m47s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m4s
2025-11-05 14:01:20 +08:00
严浩
2ba453bbed feat(app-store): 添加主题模式类型定义和初始值配置
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m9s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m31s
更新 useColorMode 钩子的类型参数,明确指定为 BasicColorSchema 类型,
并设置 initialValue 为 'auto',确保主题模式的类型安全和默认行为。
同时添加 attribute 配置项以支持 class 属性切换。
2025-11-05 13:45:15 +08:00
严浩
4b645bb916 feat(auto-imports): 添加 routeI18nT 类型声明
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
CI/CD Pipeline / playwright (push) Has been cancelled
2025-11-05 13:41:46 +08:00
0a8f1f8248 chore(deps): update dependency happy-dom to v20.0.8
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 3m40s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m0s
2025-11-05 08:29:46 +08:00
eaafbef793 chore(deps): update dependency primelocale to v2.2.2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 4m3s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m29s
2025-11-05 06:03:43 +08:00
9f57c8fe0b chore(deps): update dependency @cloudflare/vite-plugin to v1.13.14
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 3m58s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m3s
测试最新依赖 / build-and-test (push) Successful in 1m50s
测试最新依赖 / playwright (push) Successful in 2m3s
2025-11-04 22:48:37 +08:00
严浩
e912b2c710 feat(i18n): 导出路由国际化实例的翻译函数
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 5m15s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m39s
2025-11-04 11:15:25 +08:00
严浩
c0c5e9763e feat(i18n): 优化国际化路由标题设置逻辑并修复响应式问题
Some checks failed
CI/CD Pipeline / playwright (push) Successful in 4m3s
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
2025-11-04 11:09:39 +08:00
严浩
6e915a5977 feat(eslint): 添加 jsonc 插件并启用 JSON 文件键排序规则
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 4m53s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m55s
测试最新依赖 / playwright (push) Successful in 2m1s
测试最新依赖 / build-and-test (push) Successful in 2m35s
新增 `eslint-plugin-jsonc` 插件,并在 `.json` 文件中启用 `jsonc/sort-keys` 规则,
以确保本地化文件中的键名按字母顺序排列。此举有助于减少多人协作时的合并冲突,
同时提升代码一致性和可维护性。

此外,调整了 VS Code 配置项顺序以优化读写逻辑,并更新相关依赖版本。
2025-11-04 01:28:01 +08:00
严浩
acd7c0db13 feat(i18n): 强制路由标题键名按字母顺序排序
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m18s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m41s
2025-11-03 23:41:36 +08:00
1ad46a62fd chore(deps): update dependency vite-plugin-image-optimizer to v2.0.3
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m18s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m47s
2025-11-03 20:47:17 +08:00
bb02b796aa chore(deps): update dependency unplugin-vue-router to v0.16.1
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m18s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m26s
2025-11-03 17:45:06 +08:00
严浩
a4ea7ce56e fix(useMetaLayoutsMenuOptions): 移除调试日志输出
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m16s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m40s
2025-11-03 16:42:40 +08:00
严浩
166d76d980 feat(router): 支持通过 activeMenuName 指定菜单高亮路径
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 2m18s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m24s
2025-11-03 15:54:11 +08:00
严浩
f9f82e4d29 feat(i18n): 引入 routeI18nInstance 以支持路由菜单标题的多语言处理
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 5m9s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m48s
2025-11-03 15:03:22 +08:00
严浩
b4fcde324d feat(auth): 添加用户认证模块与登录页面
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 4m9s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m38s
2025-11-03 13:46:47 +08:00
严浩
b669889bb0 refactor(plugins): 重构插件自动加载逻辑
Some checks failed
CI/CD Pipeline / playwright (push) Failing after 7m17s
CI/CD Pipeline / build-and-deploy (push) Has been skipped
2025-11-03 11:52:54 +08:00
严浩
8a3b9e03fd feat(router): 添加路由就绪等待逻辑
Some checks failed
CI/CD Pipeline / playwright (push) Failing after 7m9s
CI/CD Pipeline / build-and-deploy (push) Has been skipped
2025-11-03 11:41:35 +08:00
ec02658ede chore(deps): update dependency happy-dom to v20.0.7
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m18s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m23s
2025-11-03 07:18:20 +08:00
严浩
bd9acc06a8 feat(vite-plugins): 添加 vant-touch-emulator 和 eruda 脚本支持
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 4m20s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m21s
测试最新依赖 / build-and-test (push) Successful in 2m10s
测试最新依赖 / playwright (push) Successful in 2m15s
2025-11-03 01:16:27 +08:00
严浩
f790691d5a fix(useMetaLayoutsNMenuOptions): 优化路由标题设置逻辑
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 4m4s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m39s
2025-11-02 23:05:20 +08:00
严浩
838d5cfb6e fix(useMetaLayoutsMenuOptions): 调整路由标题设置逻辑以支持多语言
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 4m17s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m27s
2025-11-02 22:33:06 +08:00
ac544a8ff5 chore(deps): update dependency wrangler to v4.45.2
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m18s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m25s
2025-11-02 18:20:03 +08:00
严浩
e7a4a7aff9 fix: 优化404页面返回按钮逻辑
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m49s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m27s
2025-11-02 17:19:16 +08:00
严浩
0d1a20d88d build(ci-cd): 添加构建时间环境变量支持
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m49s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m3s
2025-11-02 16:50:22 +08:00
19aaddc4e2 chore(deps): update dependency unplugin-icons to v22.5.0
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 3m42s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m20s
2025-11-02 12:19:18 +08:00
1e24193b84 chore(deps): update dependency primelocale to v2.2.1
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 3m39s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m41s
2025-11-02 09:14:20 +08:00
cdec0c1a23 chore(deps): update dependency @types/node to v22.18.13
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 2m5s
CI/CD Pipeline / build-and-deploy (push) Successful in 3m49s
2025-11-02 06:36:37 +08:00
94cdecb075 chore(deps): update all non-major dependencies
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / playwright (push) Successful in 4m6s
CI/CD Pipeline / build-and-deploy (push) Successful in 2m24s
2025-11-02 04:01:43 +08:00
严浩
7f0cf5dd8f feat(package): 添加 sharp 依赖,版本为 0.34.4
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 5m0s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m17s
测试最新依赖 / build-and-test (push) Successful in 1m58s
测试最新依赖 / playwright (push) Successful in 2m39s
2025-10-31 19:15:38 +08:00
严浩
c8b8a3caa4 fix(use-safe-n-form): 更改 formRef 为 formInst
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 3m38s
CI/CD Pipeline / build-and-deploy (push) Successful in 3m46s
2025-10-31 13:43:27 +08:00
严浩
48eb653f1a feat(demo): 添加 Naive UI 组件表单演示功能
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
CI/CD Pipeline / playwright (push) Has been cancelled
2025-10-31 13:40:23 +08:00
82 changed files with 6287 additions and 4100 deletions

View File

@@ -0,0 +1,39 @@
{
"image": "ghcr.io/yanhao98/h-devcontainer:main",
"runArgs": [
"--hostname=devcontainer-host",
"--name=${localWorkspaceFolderBasename}-devcontainer"
],
"forwardPorts": [4730, 4731, 5901],
"portsAttributes": {
"4730": { "label": "开发服务器端口", "onAutoForward": "notify" },
"4731": { "label": "预览服务器端口", "onAutoForward": "notify" }
},
"containerEnv": {
"TZ": "${localEnv:TZ:Asia/Shanghai}"
},
"customizations": {
"vscode": {
"extensions": ["prettier.prettier-vscode", "vue.volar"],
"settings": {
// "tasks": { "version": "2.0.0", "tasks": [] },
"github.copilot.chat.codeGeneration.instructions": [
{
"text": "This dev container includes a lightweight Fluxbox based desktop that can be accessed using a VNC viewer or the web. GUI-based commands executed from the built-in VS Code terminal will open on the desktop automatically."
}
]
}
}
},
"mounts": [
"source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
"source=${localWorkspaceFolder}/.devcontainer/lifecycle-scripts.d,target=/usr/local/etc/lifecycle-scripts.d,type=bind,consistency=delegated"
],
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind,consistency=delegated",
"initializeCommand": "docker pull ghcr.io/yanhao98/h-devcontainer:main;",
"onCreateCommand": "/usr/local/bin/run-lifecycle-scripts.sh onCreateCommand",
"updateContentCommand": "/usr/local/bin/run-lifecycle-scripts.sh updateContentCommand",
"postCreateCommand": "/usr/local/bin/run-lifecycle-scripts.sh postCreateCommand",
"postStartCommand": "/usr/local/bin/run-lifecycle-scripts.sh postStartCommand",
"postAttachCommand": "/usr/local/bin/run-lifecycle-scripts.sh postAttachCommand"
}

View File

@@ -0,0 +1,14 @@
#!/bin/zsh -eu
h-setup-zh-locale
h-setup-bun-bin
h-setup-pnpm-bin
h-setup-chromium
h-setup-desktop-lite
h-install-node-modules
echo "-----------------------------"
echo "开发容器已启动并配置完成!"
echo "-----------------------------"

View File

@@ -14,10 +14,10 @@ on:
jobs: jobs:
playwright: playwright:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: mcr.microsoft.com/playwright:v1.56.1-noble container: mcr.microsoft.com/playwright:v1.57.0-noble
steps: steps:
- name: ⚙️ 设置 Node 环境 - name: ⚙️ 设置 Node 环境
uses: yanhao98/composite-actions/setup-node-environment@25eb4dc0c134cc9df2b7c569aa54140a366b45a8 uses: yanhao98/composite-actions/setup-node-environment@faab20ac2f9c85dfce1a4147fca493bf632bd744
# - name: 📥 安装 Playwright 浏览器 # - name: 📥 安装 Playwright 浏览器
# run: pnpm exec playwright install --with-deps # run: pnpm exec playwright install --with-deps
- name: 📦 构建项目 - name: 📦 构建项目
@@ -32,13 +32,15 @@ jobs:
steps: steps:
- name: 🛠️ 设置Node环境 - name: 🛠️ 设置Node环境
uses: yanhao98/composite-actions/setup-node-environment@25eb4dc0c134cc9df2b7c569aa54140a366b45a8 uses: yanhao98/composite-actions/setup-node-environment@faab20ac2f9c85dfce1a4147fca493bf632bd744
- name: 🔍 静态代码分析 - name: 🔍 静态代码分析
run: pnpm run lint run: pnpm run lint
- name: 📦 构建项目 - name: 📦 构建项目
run: pnpm run build-only run: |
export VITE_APP_BUILD_TIME=$(date +"%Y-%m-%d %H:%M:%S")
pnpm run build-only
env: env:
VITE_APP_BUILD_COMMIT: ${{ github.sha }} VITE_APP_BUILD_COMMIT: ${{ github.sha }}

View File

@@ -60,7 +60,7 @@ jobs:
playwright: playwright:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: mcr.microsoft.com/playwright:v1.56.1-noble container: mcr.microsoft.com/playwright:v1.57.0-noble
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
with: with:

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@ yarn-error.log*
pnpm-debug.log* pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
.pnpm-store
node_modules node_modules
.DS_Store .DS_Store
dist dist

View File

@@ -8,6 +8,6 @@ cat $1
echo "🟢 [Commit-msg] Node 版本:$(node -v)" echo "🟢 [Commit-msg] Node 版本:$(node -v)"
# pnpm exec commitlint --edit $1 # pnpm exec commitlint --edit $1
time node node_modules/@commitlint/cli/cli.js --edit $1 node node_modules/@commitlint/cli/cli.js --edit $1
echo "📝 [Commit-msg] commit-msg 钩子完成!" echo "📝 [Commit-msg] commit-msg 钩子完成!"

View File

@@ -1,4 +1,4 @@
# 此钩子在 git merge 或 git pull 成功完成后运行。 # 此钩子在 git merge 或 git pull 成功完成后运行。
echo "🔗 [Post-merge] 正在安装依赖..." echo "🔗 [Post-merge] 正在安装依赖..."
time pnpm install pnpm install
echo "🔗 [Post-merge] 依赖安装完成!" echo "🔗 [Post-merge] 依赖安装完成!"

View File

@@ -1,6 +1,6 @@
# 此钩子在执行 git commit 命令时,在创建提交之前运行。 # 此钩子在执行 git commit 命令时,在创建提交之前运行。
echo "🧹 [Pre-commit] 正在运行 lint-staged..." echo "🧹 [Pre-commit] 正在运行 lint-staged..."
time pnpm exec lint-staged pnpm exec lint-staged
time pnpm run lint:vue-i18n-extract pnpm run lint:vue-i18n-extract
# time pnpm run type-check # pnpm run type-check
echo "🧹 [Pre-commit] lint-staged 完成!" echo "🧹 [Pre-commit] lint-staged 完成!"

3
.ignore Normal file
View File

@@ -0,0 +1,3 @@
# VS Code 搜索忽略
pnpm-lock.yaml

8
.npmrc
View File

@@ -1,9 +1 @@
# registry=https://registry.npmmirror.com/ # registry=https://registry.npmmirror.com/
# https://pnpm.io/zh/npmrc#node-mirrorltreleasedir
use-node-version=24.7.0
node-mirror:release=https://npmmirror.com/mirrors/node/ # pnpm config set node-mirror:release=https://npmmirror.com/mirrors/node/
node-mirror:rc=https://npmmirror.com/mirrors/node-rc/
node-mirror:nightly=https://npmmirror.com/mirrors/node-nightly/
# shamefully-hoist=true

View File

@@ -4,5 +4,6 @@
"tabWidth": 2, "tabWidth": 2,
"singleQuote": true, "singleQuote": true,
"printWidth": 100, "printWidth": 100,
"trailingComma": "all" "trailingComma": "all",
"plugins": ["@prettier/plugin-oxc"]
} }

View File

@@ -2,10 +2,11 @@
"recommendations": [ "recommendations": [
"Vue.volar", "Vue.volar",
"vitest.explorer", "vitest.explorer",
"ms-playwright.playwright",
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig", "EditorConfig.EditorConfig",
"oxc.oxc-vscode", "oxc.oxc-vscode",
"esbenp.prettier-vscode" "prettier.prettier-vscode",
"stylelint.vscode-stylelint",
"lokalise.i18n-ally"
] ]
} }

58
.vscode/settings.json vendored
View File

@@ -1,27 +1,56 @@
{ {
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.preferences.autoImportFileExcludePatterns": [
"vue-router$",
"**/src/composables/**",
"**/*-auto-imports.ts",
"**/*-auto-imports.types.ts"
],
"search.exclude": {
"public/report-ui-dist": true
},
// ============================================================
// 代码格式化相关配置
// ============================================================
"prettier.enable": true,
"files.readonlyInclude": {
"dist/**": true
},
"eslint.enable": true,
"oxc.enable": true,
"stylelint.enable": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll": "explicit", "source.fixAll": "explicit",
"source.fixAll.eslint": "explicit", "source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit",
"source.fixAll.oxc": "explicit", "source.fixAll.oxc": "explicit",
"source.organizeImports": "never" "source.fixAll.stylelint": "explicit",
"source.organizeImports": "explicit"
}, },
"editor.formatOnSave": true,
"stylelint.enable": true,
"stylelint.validate": ["css", "less", "postcss", "scss", "vue"], "stylelint.validate": ["css", "less", "postcss", "scss", "vue"],
"scss.lint.unknownAtRules": "ignore", "scss.lint.unknownAtRules": "ignore",
"css.lint.unknownAtRules": "ignore", "css.lint.unknownAtRules": "ignore",
"less.lint.unknownAtRules": "ignore", "less.lint.unknownAtRules": "ignore",
"editor.defaultFormatter": "prettier.prettier-vscode",
"eslint.enable": true, "[typescript]": {
"oxc.enable": true, "editor.defaultFormatter": "prettier.prettier-vscode"
"[vue]": { },
"editor.defaultFormatter": "esbenp.prettier-vscode" "[vue]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
}, },
"editor.defaultFormatter": "esbenp.prettier-vscode",
// ============================================================
// i18n-ally 配置
// ============================================================
// >>>>> // >>>>>
"i18n-ally.readonly": false,
"i18n-ally.namespace": false /* @intlify/unplugin-vue-i18n */, "i18n-ally.namespace": false /* @intlify/unplugin-vue-i18n */,
"i18n-ally.localesPaths": ["src/locales/demo", "src/locales"], "i18n-ally.localesPaths": ["src/locales/demo", "src/locales"],
// https://github.com/lokalise/i18n-ally/wiki/Path-Matcher // https://github.com/lokalise/i18n-ally/wiki/Path-Matcher
@@ -30,12 +59,7 @@
"i18n-ally.enabledParsers": ["json"], "i18n-ally.enabledParsers": ["json"],
"i18n-ally.keystyle": "nested", "i18n-ally.keystyle": "nested",
"i18n-ally.sourceLanguage": "zh-CN", // 翻译源语言 (源文件) 根据此语言文件翻译其他语言文件的变量和内容 "i18n-ally.sourceLanguage": "zh-CN", // 翻译源语言 (源文件) 根据此语言文件翻译其他语言文件的变量和内容
"i18n-ally.displayLanguage": "zh-CN", // 显示语言 (显示文件/翻译文件) "i18n-ally.displayLanguage": "zh-CN" // 显示语言 (显示文件/翻译文件)
// <<<<< // <<<<<
// https://github.com/copilot/share/8a1a019a-0180-80e7-8141-a40be02c4006
// "iconify.customCollectionJsonPaths": ["https://example.com/my-icons.json", "./local/icons.json"], // "iconify.customCollectionJsonPaths": ["https://example.com/my-icons.json", "./local/icons.json"],
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.preferences.autoImportFileExcludePatterns": ["vue-router/auto$"]
} }

24
.vscode/tasks.json vendored
View File

@@ -6,16 +6,12 @@
"script": "dev", "script": "dev",
"label": "🚀 dev", "label": "🚀 dev",
"detail": "启动开发服务器", "detail": "启动开发服务器",
"problemMatcher": { "problemMatcher": [],
"pattern": { "regexp": "." },
"background": {
"activeOnStart": true,
"beginsPattern": "VITE.*ready in",
"endsPattern": "(Local|Network):.*http"
}
},
"isBackground": true, "isBackground": true,
"presentation": { "reveal": "always", "panel": "dedicated" }, "presentation": {
"reveal": "always", // 控制运行任务的终端是否显示。可按选项 "revealProblems" 进行替代。默认设置为“始终”。
"panel": "dedicated" // dedicated一个任务独占一个终端方便查看特定任务的日志不会被其他任务干扰。
},
"group": { "kind": "build", "isDefault": false } "group": { "kind": "build", "isDefault": false }
}, },
{ {
@@ -23,7 +19,6 @@
"script": "build-only", "script": "build-only",
"label": "🔨 build-only", "label": "🔨 build-only",
"detail": "" /* VSCode 使 package.json scripts[scriptName] detail */, "detail": "" /* VSCode 使 package.json scripts[scriptName] detail */,
"problemMatcher": ["$tsc"],
"presentation": { "reveal": "always", "panel": "shared" }, "presentation": { "reveal": "always", "panel": "shared" },
"group": { "kind": "none", "isDefault": false } "group": { "kind": "none", "isDefault": false }
}, },
@@ -33,14 +28,7 @@
"label": "☁️ wrangler:dev", "label": "☁️ wrangler:dev",
"detail": "启动 Cloudflare Workers 开发服务器,相当于预览", "detail": "启动 Cloudflare Workers 开发服务器,相当于预览",
"dependsOn": ["🔨 build-only"], "dependsOn": ["🔨 build-only"],
"problemMatcher": { "problemMatcher": [],
"pattern": { "regexp": "." },
"background": {
"activeOnStart": true,
"beginsPattern": "wrangler dev",
"endsPattern": "Ready on"
}
},
"isBackground": true, "isBackground": true,
"presentation": { "reveal": "always", "panel": "dedicated" }, "presentation": { "reveal": "always", "panel": "dedicated" },
"group": { "kind": "build", "isDefault": false } "group": { "kind": "build", "isDefault": false }

View File

@@ -9,6 +9,7 @@ Vue 3 TypeScript application with Vite.
## 开发服务器 ## 开发服务器
- **不要启动开发服务器**: 开发服务器通常已经由用户启动。除非特别要求,否则不要执行 `pnpm dev` 之类的命令。 - **不要启动开发服务器**: 开发服务器通常已经由用户启动。除非特别要求,否则不要执行 `pnpm dev` 之类的命令。
- **不要执行 Playwright 测试**: 除非用户明确要求,否则不要运行 Playwright 端到端测试。
### Routing & Layouts ### Routing & Layouts
@@ -46,25 +47,6 @@ Multiple auto-import systems are active:
Project has multiple UI frameworks configured: Project has multiple UI frameworks configured:
- **Naive UI** - **Naive UI**
- **Form Layout**: When using `NGrid` for form layouts, prefer `NFormItemGi` over nesting `NFormItem` inside `NGridItem` for more concise code.
```vue
<!-- ❌ Avoid: Verbose nesting -->
<NGrid :cols="4">
<NGridItem>
<NFormItem label="Username">
<NInput />
</NFormItem>
</NGridItem>
</NGrid>
<!-- ✅ Use: Concise and direct -->
<NGrid :cols="4">
<NFormItemGi label="Username">
<NInput />
</NFormItemGi>
</NGrid>
```
- **PrimeVue**: - **PrimeVue**:

664
auto-imports.d.ts vendored
View File

@@ -6,333 +6,335 @@
// biome-ignore lint: disable // biome-ignore lint: disable
export {} export {}
declare global { declare global {
const ConfirmationService: typeof import('utils4u/primevue')['ConfirmationService'] const ConfirmationService: typeof import('utils4u/primevue').ConfirmationService
const DialogService: typeof import('utils4u/primevue')['DialogService'] const DialogService: typeof import('utils4u/primevue').DialogService
const EffectScope: typeof import('vue')['EffectScope'] const EffectScope: typeof import('vue').EffectScope
const ToastService: typeof import('utils4u/primevue')['ToastService'] const ToastService: typeof import('utils4u/primevue').ToastService
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
const arrayToTree: typeof import('utils4u/array')['arrayToTree'] const arrayToTree: typeof import('utils4u/array').arrayToTree
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] const asyncComputed: typeof import('@vueuse/core').asyncComputed
const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] const autoResetRef: typeof import('@vueuse/core').autoResetRef
const computed: typeof import('vue')['computed'] const computed: typeof import('vue').computed
const computedAsync: typeof import('@vueuse/core')['computedAsync'] const computedAsync: typeof import('@vueuse/core').computedAsync
const computedEager: typeof import('@vueuse/core')['computedEager'] const computedEager: typeof import('@vueuse/core').computedEager
const computedInject: typeof import('@vueuse/core')['computedInject'] const computedInject: typeof import('@vueuse/core').computedInject
const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] const computedWithControl: typeof import('@vueuse/core').computedWithControl
const consola: typeof import('consola/browser')['consola'] const consola: typeof import('consola/browser').consola
const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] const controlledComputed: typeof import('@vueuse/core').controlledComputed
const controlledRef: typeof import('@vueuse/core')['controlledRef'] const controlledRef: typeof import('@vueuse/core').controlledRef
const convertFileToBase64: typeof import('utils4u/browser')['convertFileToBase64'] const convertFileToBase64: typeof import('utils4u/browser').convertFileToBase64
const createApp: typeof import('vue')['createApp'] const createApp: typeof import('vue').createApp
const createEventHook: typeof import('@vueuse/core')['createEventHook'] const createEventHook: typeof import('@vueuse/core').createEventHook
const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] const createGlobalState: typeof import('@vueuse/core').createGlobalState
const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] const createInjectionState: typeof import('@vueuse/core').createInjectionState
const createLogGuard: typeof import('utils4u/vue-router')['createLogGuard'] const createLogGuard: typeof import('utils4u/vue-router').createLogGuard
const createNProgressGuard: typeof import('utils4u/vue-router')['createNProgressGuard'] const createNProgressGuard: typeof import('utils4u/vue-router').createNProgressGuard
const createPinia: typeof import('pinia')['createPinia'] const createPinia: typeof import('pinia').createPinia
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] const createReactiveFn: typeof import('@vueuse/core').createReactiveFn
const createRef: typeof import('@vueuse/core')['createRef'] const createRef: typeof import('@vueuse/core').createRef
const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate'] const createReusableTemplate: typeof import('@vueuse/core').createReusableTemplate
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] const createSharedComposable: typeof import('@vueuse/core').createSharedComposable
const createStackGuard: typeof import('utils4u/vue-router')['createStackGuard'] const createStackGuard: typeof import('utils4u/vue-router').createStackGuard
const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] const createTemplatePromise: typeof import('@vueuse/core').createTemplatePromise
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] const createUnrefFn: typeof import('@vueuse/core').createUnrefFn
const customRef: typeof import('vue')['customRef'] const customRef: typeof import('vue').customRef
const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] const debouncedRef: typeof import('@vueuse/core').debouncedRef
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] const debouncedWatch: typeof import('@vueuse/core').debouncedWatch
const deepFreeze: typeof import('deep-freeze-es6')['default'] const deepFreeze: typeof import('deep-freeze-es6').default
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] const defineAsyncComponent: typeof import('vue').defineAsyncComponent
const defineComponent: typeof import('vue')['defineComponent'] const defineBasicLoader: typeof import('unplugin-vue-router/data-loaders/basic').defineBasicLoader
const defineStore: typeof import('pinia')['defineStore'] const defineComponent: typeof import('vue').defineComponent
const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] const defineStore: typeof import('pinia').defineStore
const effectScope: typeof import('vue')['effectScope'] const eagerComputed: typeof import('@vueuse/core').eagerComputed
const extendRef: typeof import('@vueuse/core')['extendRef'] const effectScope: typeof import('vue').effectScope
const getActivePinia: typeof import('pinia')['getActivePinia'] const extendRef: typeof import('@vueuse/core').extendRef
const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getActivePinia: typeof import('pinia').getActivePinia
const getCurrentScope: typeof import('vue')['getCurrentScope'] const getCurrentInstance: typeof import('vue').getCurrentInstance
const getCurrentWatcher: typeof import('vue')['getCurrentWatcher'] const getCurrentScope: typeof import('vue').getCurrentScope
const h: typeof import('vue')['h'] const getCurrentWatcher: typeof import('vue').getCurrentWatcher
const i18nInstance: typeof import('./src/locales-utils/i18n-auto-imports')['i18nInstance'] const h: typeof import('vue').h
const i18nRouteMessages: typeof import('./src/locales-utils/route-messages/route-messages-auto-imports')['i18nRouteMessages'] const i18nInstance: typeof import('./src/locales-utils/i18n-auto-imports').i18nInstance
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] const i18nRouteMessages: typeof import('./src/locales-utils/route-messages/route-messages-auto-imports').i18nRouteMessages
const inject: typeof import('vue')['inject'] const ignorableWatch: typeof import('@vueuse/core').ignorableWatch
const injectLocal: typeof import('@vueuse/core')['injectLocal'] const inject: typeof import('vue').inject
const isDefined: typeof import('@vueuse/core')['isDefined'] const injectLocal: typeof import('@vueuse/core').injectLocal
const isProxy: typeof import('vue')['isProxy'] const isDefined: typeof import('@vueuse/core').isDefined
const isReactive: typeof import('vue')['isReactive'] const isProxy: typeof import('vue').isProxy
const isReadonly: typeof import('vue')['isReadonly'] const isReactive: typeof import('vue').isReactive
const isRef: typeof import('vue')['isRef'] const isReadonly: typeof import('vue').isReadonly
const isShallow: typeof import('vue')['isShallow'] const isRef: typeof import('vue').isRef
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] const isShallow: typeof import('vue').isShallow
const mapActions: typeof import('pinia')['mapActions'] const makeDestructurable: typeof import('@vueuse/core').makeDestructurable
const mapGetters: typeof import('pinia')['mapGetters'] const mapActions: typeof import('pinia').mapActions
const mapState: typeof import('pinia')['mapState'] const mapGetters: typeof import('pinia').mapGetters
const mapStores: typeof import('pinia')['mapStores'] const mapState: typeof import('pinia').mapState
const mapWritableState: typeof import('pinia')['mapWritableState'] const mapStores: typeof import('pinia').mapStores
const markRaw: typeof import('vue')['markRaw'] const mapWritableState: typeof import('pinia').mapWritableState
const nextTick: typeof import('vue')['nextTick'] const markRaw: typeof import('vue').markRaw
const onActivated: typeof import('vue')['onActivated'] const nextTick: typeof import('vue').nextTick
const onBeforeMount: typeof import('vue')['onBeforeMount'] const onActivated: typeof import('vue').onActivated
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] const onBeforeMount: typeof import('vue').onBeforeMount
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] const onBeforeUnmount: typeof import('vue').onBeforeUnmount
const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] const onBeforeUpdate: typeof import('vue').onBeforeUpdate
const onDeactivated: typeof import('vue')['onDeactivated'] const onClickOutside: typeof import('@vueuse/core').onClickOutside
const onElementRemoval: typeof import('@vueuse/core')['onElementRemoval'] const onDeactivated: typeof import('vue').onDeactivated
const onErrorCaptured: typeof import('vue')['onErrorCaptured'] const onElementRemoval: typeof import('@vueuse/core').onElementRemoval
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] const onErrorCaptured: typeof import('vue').onErrorCaptured
const onLongPress: typeof import('@vueuse/core')['onLongPress'] const onKeyStroke: typeof import('@vueuse/core').onKeyStroke
const onMounted: typeof import('vue')['onMounted'] const onLongPress: typeof import('@vueuse/core').onLongPress
const onRenderTracked: typeof import('vue')['onRenderTracked'] const onMounted: typeof import('vue').onMounted
const onRenderTriggered: typeof import('vue')['onRenderTriggered'] const onRenderTracked: typeof import('vue').onRenderTracked
const onScopeDispose: typeof import('vue')['onScopeDispose'] const onRenderTriggered: typeof import('vue').onRenderTriggered
const onServerPrefetch: typeof import('vue')['onServerPrefetch'] const onScopeDispose: typeof import('vue').onScopeDispose
const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] const onServerPrefetch: typeof import('vue').onServerPrefetch
const onUnmounted: typeof import('vue')['onUnmounted'] const onStartTyping: typeof import('@vueuse/core').onStartTyping
const onUpdated: typeof import('vue')['onUpdated'] const onUnmounted: typeof import('vue').onUnmounted
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] const onUpdated: typeof import('vue').onUpdated
const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] const onWatcherCleanup: typeof import('vue').onWatcherCleanup
const provide: typeof import('vue')['provide'] const pausableWatch: typeof import('@vueuse/core').pausableWatch
const provideLocal: typeof import('@vueuse/core')['provideLocal'] const provide: typeof import('vue').provide
const reactify: typeof import('@vueuse/core')['reactify'] const provideLocal: typeof import('@vueuse/core').provideLocal
const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] const reactify: typeof import('@vueuse/core').reactify
const reactive: typeof import('vue')['reactive'] const reactifyObject: typeof import('@vueuse/core').reactifyObject
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed'] const reactive: typeof import('vue').reactive
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit'] const reactiveComputed: typeof import('@vueuse/core').reactiveComputed
const reactivePick: typeof import('@vueuse/core')['reactivePick'] const reactiveOmit: typeof import('@vueuse/core').reactiveOmit
const readonly: typeof import('vue')['readonly'] const reactivePick: typeof import('@vueuse/core').reactivePick
const ref: typeof import('vue')['ref'] const readonly: typeof import('vue').readonly
const refAutoReset: typeof import('@vueuse/core')['refAutoReset'] const ref: typeof import('vue').ref
const refDebounced: typeof import('@vueuse/core')['refDebounced'] const refAutoReset: typeof import('@vueuse/core').refAutoReset
const refDefault: typeof import('@vueuse/core')['refDefault'] const refDebounced: typeof import('@vueuse/core').refDebounced
const refThrottled: typeof import('@vueuse/core')['refThrottled'] const refDefault: typeof import('@vueuse/core').refDefault
const refWithControl: typeof import('@vueuse/core')['refWithControl'] const refManualReset: typeof import('@vueuse/core').refManualReset
const resolveComponent: typeof import('vue')['resolveComponent'] const refThrottled: typeof import('@vueuse/core').refThrottled
const resolveRef: typeof import('@vueuse/core')['resolveRef'] const refWithControl: typeof import('@vueuse/core').refWithControl
const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] const resolveComponent: typeof import('vue').resolveComponent
const setActivePinia: typeof import('pinia')['setActivePinia'] const resolveRef: typeof import('@vueuse/core').resolveRef
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] const routeI18nInstance: typeof import('./src/locales-utils/i18n-auto-imports').routeI18nInstance
const setViewportCSSVars: typeof import('utils4u/browser')['setViewportCSSVars'] const routeI18nT: typeof import('./src/locales-utils/i18n-auto-imports').routeI18nT
const shallowReactive: typeof import('vue')['shallowReactive'] const setActivePinia: typeof import('pinia').setActivePinia
const shallowReadonly: typeof import('vue')['shallowReadonly'] const setMapStoreSuffix: typeof import('pinia').setMapStoreSuffix
const shallowRef: typeof import('vue')['shallowRef'] const setViewportCSSVars: typeof import('utils4u/browser').setViewportCSSVars
const showOpenFilePicker: typeof import('utils4u/browser')['showOpenFilePicker'] const shallowReactive: typeof import('vue').shallowReactive
const storeToRefs: typeof import('pinia')['storeToRefs'] const shallowReadonly: typeof import('vue').shallowReadonly
const syncRef: typeof import('@vueuse/core')['syncRef'] const shallowRef: typeof import('vue').shallowRef
const syncRefs: typeof import('@vueuse/core')['syncRefs'] const showOpenFilePicker: typeof import('utils4u/browser').showOpenFilePicker
const templateRef: typeof import('@vueuse/core')['templateRef'] const storeToRefs: typeof import('pinia').storeToRefs
const throttledRef: typeof import('@vueuse/core')['throttledRef'] const syncRef: typeof import('@vueuse/core').syncRef
const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] const syncRefs: typeof import('@vueuse/core').syncRefs
const toRaw: typeof import('vue')['toRaw'] const templateRef: typeof import('@vueuse/core').templateRef
const toReactive: typeof import('@vueuse/core')['toReactive'] const throttledRef: typeof import('@vueuse/core').throttledRef
const toRef: typeof import('vue')['toRef'] const throttledWatch: typeof import('@vueuse/core').throttledWatch
const toRefs: typeof import('vue')['toRefs'] const toRaw: typeof import('vue').toRaw
const toValue: typeof import('vue')['toValue'] const toReactive: typeof import('@vueuse/core').toReactive
const triggerRef: typeof import('vue')['triggerRef'] const toRef: typeof import('vue').toRef
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] const toRefs: typeof import('vue').toRefs
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] const toValue: typeof import('vue').toValue
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] const triggerRef: typeof import('vue').triggerRef
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] const tryOnBeforeMount: typeof import('@vueuse/core').tryOnBeforeMount
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] const tryOnBeforeUnmount: typeof import('@vueuse/core').tryOnBeforeUnmount
const unref: typeof import('vue')['unref'] const tryOnMounted: typeof import('@vueuse/core').tryOnMounted
const unrefElement: typeof import('@vueuse/core')['unrefElement'] const tryOnScopeDispose: typeof import('@vueuse/core').tryOnScopeDispose
const until: typeof import('@vueuse/core')['until'] const tryOnUnmounted: typeof import('@vueuse/core').tryOnUnmounted
const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] const unref: typeof import('vue').unref
const useAnimate: typeof import('@vueuse/core')['useAnimate'] const unrefElement: typeof import('@vueuse/core').unrefElement
const useAppStore: typeof import('./src/stores/app-store-auto-imports')['useAppStore'] const until: typeof import('@vueuse/core').until
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference'] const useActiveElement: typeof import('@vueuse/core').useActiveElement
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] const useAnimate: typeof import('@vueuse/core').useAnimate
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] const useAppStore: typeof import('./src/stores/app-store-auto-imports').useAppStore
const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] const useArrayDifference: typeof import('@vueuse/core').useArrayDifference
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] const useArrayEvery: typeof import('@vueuse/core').useArrayEvery
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast'] const useArrayFilter: typeof import('@vueuse/core').useArrayFilter
const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes'] const useArrayFind: typeof import('@vueuse/core').useArrayFind
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] const useArrayFindIndex: typeof import('@vueuse/core').useArrayFindIndex
const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] const useArrayFindLast: typeof import('@vueuse/core').useArrayFindLast
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] const useArrayIncludes: typeof import('@vueuse/core').useArrayIncludes
const useArraySome: typeof import('@vueuse/core')['useArraySome'] const useArrayJoin: typeof import('@vueuse/core').useArrayJoin
const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique'] const useArrayMap: typeof import('@vueuse/core').useArrayMap
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] const useArrayReduce: typeof import('@vueuse/core').useArrayReduce
const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] const useArraySome: typeof import('@vueuse/core').useArraySome
const useAttrs: typeof import('vue')['useAttrs'] const useArrayUnique: typeof import('@vueuse/core').useArrayUnique
const useBase64: typeof import('@vueuse/core')['useBase64'] const useAsyncQueue: typeof import('@vueuse/core').useAsyncQueue
const useBattery: typeof import('@vueuse/core')['useBattery'] const useAsyncState: typeof import('@vueuse/core').useAsyncState
const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] const useAttrs: typeof import('vue').useAttrs
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] const useAuthStore: typeof import('./src/stores/auth-store-auto-imports').useAuthStore
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] const useBase64: typeof import('@vueuse/core').useBase64
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] const useBattery: typeof import('@vueuse/core').useBattery
const useCached: typeof import('@vueuse/core')['useCached'] const useBluetooth: typeof import('@vueuse/core').useBluetooth
const useClipboard: typeof import('@vueuse/core')['useClipboard'] const useBreakpoints: typeof import('@vueuse/core').useBreakpoints
const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems'] const useBroadcastChannel: typeof import('@vueuse/core').useBroadcastChannel
const useCloned: typeof import('@vueuse/core')['useCloned'] const useBrowserLocation: typeof import('@vueuse/core').useBrowserLocation
const useColorMode: typeof import('@vueuse/core')['useColorMode'] const useCached: typeof import('@vueuse/core').useCached
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] const useClipboard: typeof import('@vueuse/core').useClipboard
const useCountdown: typeof import('@vueuse/core')['useCountdown'] const useClipboardItems: typeof import('@vueuse/core').useClipboardItems
const useCounter: typeof import('@vueuse/core')['useCounter'] const useCloned: typeof import('@vueuse/core').useCloned
const useCssModule: typeof import('vue')['useCssModule'] const useColorMode: typeof import('@vueuse/core').useColorMode
const useCssVar: typeof import('@vueuse/core')['useCssVar'] const useConfirmDialog: typeof import('@vueuse/core').useConfirmDialog
const useCssVars: typeof import('vue')['useCssVars'] const useCountdown: typeof import('@vueuse/core').useCountdown
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement'] const useCounter: typeof import('@vueuse/core').useCounter
const useCycleList: typeof import('@vueuse/core')['useCycleList'] const useCssModule: typeof import('vue').useCssModule
const useDark: typeof import('@vueuse/core')['useDark'] const useCssVar: typeof import('@vueuse/core').useCssVar
const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] const useCssVars: typeof import('vue').useCssVars
const useDebounce: typeof import('@vueuse/core')['useDebounce'] const useCurrentElement: typeof import('@vueuse/core').useCurrentElement
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn'] const useCycleList: typeof import('@vueuse/core').useCycleList
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] const useDark: typeof import('@vueuse/core').useDark
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] const useDateFormat: typeof import('@vueuse/core').useDateFormat
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] const useDebounce: typeof import('@vueuse/core').useDebounce
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] const useDebounceFn: typeof import('@vueuse/core').useDebounceFn
const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] const useDebouncedRefHistory: typeof import('@vueuse/core').useDebouncedRefHistory
const useDialog: typeof import('naive-ui')['useDialog'] const useDeviceMotion: typeof import('@vueuse/core').useDeviceMotion
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] const useDeviceOrientation: typeof import('@vueuse/core').useDeviceOrientation
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] const useDevicePixelRatio: typeof import('@vueuse/core').useDevicePixelRatio
const useDraggable: typeof import('@vueuse/core')['useDraggable'] const useDevicesList: typeof import('@vueuse/core').useDevicesList
const useDropZone: typeof import('@vueuse/core')['useDropZone'] const useDialog: typeof import('naive-ui').useDialog
const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] const useDisplayMedia: typeof import('@vueuse/core').useDisplayMedia
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] const useDocumentVisibility: typeof import('@vueuse/core').useDocumentVisibility
const useElementHover: typeof import('@vueuse/core')['useElementHover'] const useDraggable: typeof import('@vueuse/core').useDraggable
const useElementSize: typeof import('@vueuse/core')['useElementSize'] const useDropZone: typeof import('@vueuse/core').useDropZone
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] const useElementBounding: typeof import('@vueuse/core').useElementBounding
const useEventBus: typeof import('@vueuse/core')['useEventBus'] const useElementByPoint: typeof import('@vueuse/core').useElementByPoint
const useEventListener: typeof import('@vueuse/core')['useEventListener'] const useElementHover: typeof import('@vueuse/core').useElementHover
const useEventSource: typeof import('@vueuse/core')['useEventSource'] const useElementSize: typeof import('@vueuse/core').useElementSize
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] const useElementVisibility: typeof import('@vueuse/core').useElementVisibility
const useFavicon: typeof import('@vueuse/core')['useFavicon'] const useEventBus: typeof import('@vueuse/core').useEventBus
const useFetch: typeof import('@vueuse/core')['useFetch'] const useEventListener: typeof import('@vueuse/core').useEventListener
const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] const useEventSource: typeof import('@vueuse/core').useEventSource
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] const useEyeDropper: typeof import('@vueuse/core').useEyeDropper
const useFocus: typeof import('@vueuse/core')['useFocus'] const useFavicon: typeof import('@vueuse/core').useFavicon
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] const useFetch: typeof import('@vueuse/core').useFetch
const useFps: typeof import('@vueuse/core')['useFps'] const useFileDialog: typeof import('@vueuse/core').useFileDialog
const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] const useFileSystemAccess: typeof import('@vueuse/core').useFileSystemAccess
const useGamepad: typeof import('@vueuse/core')['useGamepad'] const useFocus: typeof import('@vueuse/core').useFocus
const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] const useFocusWithin: typeof import('@vueuse/core').useFocusWithin
const useI18n: typeof import('vue-i18n')['useI18n'] const useFps: typeof import('@vueuse/core').useFps
const useId: typeof import('vue')['useId'] const useFullscreen: typeof import('@vueuse/core').useFullscreen
const useIdle: typeof import('@vueuse/core')['useIdle'] const useGamepad: typeof import('@vueuse/core').useGamepad
const useImage: typeof import('@vueuse/core')['useImage'] const useGeolocation: typeof import('@vueuse/core').useGeolocation
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] const useI18n: typeof import('vue-i18n').useI18n
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] const useId: typeof import('vue').useId
const useInterval: typeof import('@vueuse/core')['useInterval'] const useIdle: typeof import('@vueuse/core').useIdle
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] const useImage: typeof import('@vueuse/core').useImage
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] const useInfiniteScroll: typeof import('@vueuse/core').useInfiniteScroll
const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] const useIntersectionObserver: typeof import('@vueuse/core').useIntersectionObserver
const useLink: typeof import('vue-router/auto')['useLink'] const useInterval: typeof import('@vueuse/core').useInterval
const useLoadingBar: typeof import('naive-ui')['useLoadingBar'] const useIntervalFn: typeof import('@vueuse/core').useIntervalFn
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] const useKeyModifier: typeof import('@vueuse/core').useKeyModifier
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] const useLastChanged: typeof import('@vueuse/core').useLastChanged
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] const useLoadingBar: typeof import('naive-ui').useLoadingBar
const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] const useLocalStorage: typeof import('@vueuse/core').useLocalStorage
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] const useMagicKeys: typeof import('@vueuse/core').useMagicKeys
const useMemoize: typeof import('@vueuse/core')['useMemoize'] const useManualRefHistory: typeof import('@vueuse/core').useManualRefHistory
const useMemory: typeof import('@vueuse/core')['useMemory'] const useMediaControls: typeof import('@vueuse/core').useMediaControls
const useMessage: typeof import('naive-ui')['useMessage'] const useMediaQuery: typeof import('@vueuse/core').useMediaQuery
const useMetaLayoutsNMenuOptions: typeof import('./src/composables/useMetaLayoutsMenuOptions')['useMetaLayoutsNMenuOptions'] const useMemoize: typeof import('@vueuse/core').useMemoize
const useModal: typeof import('naive-ui')['useModal'] const useMemory: typeof import('@vueuse/core').useMemory
const useModel: typeof import('vue')['useModel'] const useMessage: typeof import('naive-ui').useMessage
const useMounted: typeof import('@vueuse/core')['useMounted'] const useMetaLayoutsNMenuOptions: typeof import('./src/composables/useMetaLayoutsMenuOptions').useMetaLayoutsNMenuOptions
const useMouse: typeof import('@vueuse/core')['useMouse'] const useModal: typeof import('naive-ui').useModal
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] const useModel: typeof import('vue').useModel
const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] const useMounted: typeof import('@vueuse/core').useMounted
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] const useMouse: typeof import('@vueuse/core').useMouse
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] const useMouseInElement: typeof import('@vueuse/core').useMouseInElement
const useNetwork: typeof import('@vueuse/core')['useNetwork'] const useMousePressed: typeof import('@vueuse/core').useMousePressed
const useNotification: typeof import('naive-ui')['useNotification'] const useMutationObserver: typeof import('@vueuse/core').useMutationObserver
const useNow: typeof import('@vueuse/core')['useNow'] const useNavigatorLanguage: typeof import('@vueuse/core').useNavigatorLanguage
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] const useNetwork: typeof import('@vueuse/core').useNetwork
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] const useNotification: typeof import('naive-ui').useNotification
const useOnline: typeof import('@vueuse/core')['useOnline'] const useNow: typeof import('@vueuse/core').useNow
const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] const useObjectUrl: typeof import('@vueuse/core').useObjectUrl
const useParallax: typeof import('@vueuse/core')['useParallax'] const useOffsetPagination: typeof import('@vueuse/core').useOffsetPagination
const useParentElement: typeof import('@vueuse/core')['useParentElement'] const useOnline: typeof import('@vueuse/core').useOnline
const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver'] const usePageLeave: typeof import('@vueuse/core').usePageLeave
const usePermission: typeof import('@vueuse/core')['usePermission'] const useParallax: typeof import('@vueuse/core').useParallax
const usePointer: typeof import('@vueuse/core')['usePointer'] const useParentElement: typeof import('@vueuse/core').useParentElement
const usePointerLock: typeof import('@vueuse/core')['usePointerLock'] const usePerformanceObserver: typeof import('@vueuse/core').usePerformanceObserver
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] const usePermission: typeof import('@vueuse/core').usePermission
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] const usePointer: typeof import('@vueuse/core').usePointer
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast'] const usePointerLock: typeof import('@vueuse/core').usePointerLock
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] const usePointerSwipe: typeof import('@vueuse/core').usePointerSwipe
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages'] const usePreferredColorScheme: typeof import('@vueuse/core').usePreferredColorScheme
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion'] const usePreferredContrast: typeof import('@vueuse/core').usePreferredContrast
const usePreferredReducedTransparency: typeof import('@vueuse/core')['usePreferredReducedTransparency'] const usePreferredDark: typeof import('@vueuse/core').usePreferredDark
const usePrevious: typeof import('@vueuse/core')['usePrevious'] const usePreferredLanguages: typeof import('@vueuse/core').usePreferredLanguages
const usePrimevueDialogRef: typeof import('utils4u/primevue')['usePrimevueDialogRef'] const usePreferredReducedMotion: typeof import('@vueuse/core').usePreferredReducedMotion
const useRafFn: typeof import('@vueuse/core')['useRafFn'] const usePreferredReducedTransparency: typeof import('@vueuse/core').usePreferredReducedTransparency
const useRefHistory: typeof import('@vueuse/core')['useRefHistory'] const usePrevious: typeof import('@vueuse/core').usePrevious
const useRefs: typeof import('utils4u/vue-use')['useRefs'] const usePrimevueDialogRef: typeof import('utils4u/primevue').usePrimevueDialogRef
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] const useRafFn: typeof import('@vueuse/core').useRafFn
const useRoute: typeof import('vue-router')['useRoute'] const useRefHistory: typeof import('@vueuse/core').useRefHistory
const useRouter: typeof import('vue-router')['useRouter'] const useRefs: typeof import('utils4u/vue-use').useRefs
const useSSRWidth: typeof import('@vueuse/core')['useSSRWidth'] const useResizeObserver: typeof import('@vueuse/core').useResizeObserver
const useSafeNForm: typeof import('./src/utils/use-safe-n-form-auto-imports')['useSafeNForm'] const useRoute: typeof import('vue-router').useRoute
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] const useRouter: typeof import('vue-router').useRouter
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] const useSSRWidth: typeof import('@vueuse/core').useSSRWidth
const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] const useScreenOrientation: typeof import('@vueuse/core').useScreenOrientation
const useScroll: typeof import('@vueuse/core')['useScroll'] const useScreenSafeArea: typeof import('@vueuse/core').useScreenSafeArea
const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] const useScriptTag: typeof import('@vueuse/core').useScriptTag
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] const useScroll: typeof import('@vueuse/core').useScroll
const useShare: typeof import('@vueuse/core')['useShare'] const useScrollLock: typeof import('@vueuse/core').useScrollLock
const useSlots: typeof import('vue')['useSlots'] const useSessionStorage: typeof import('@vueuse/core').useSessionStorage
const useSorted: typeof import('@vueuse/core')['useSorted'] const useShare: typeof import('@vueuse/core').useShare
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] const useSlots: typeof import('vue').useSlots
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] const useSorted: typeof import('@vueuse/core').useSorted
const useStepper: typeof import('@vueuse/core')['useStepper'] const useSpeechRecognition: typeof import('@vueuse/core').useSpeechRecognition
const useStorage: typeof import('@vueuse/core')['useStorage'] const useSpeechSynthesis: typeof import('@vueuse/core').useSpeechSynthesis
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] const useStepper: typeof import('@vueuse/core').useStepper
const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] const useStorage: typeof import('@vueuse/core').useStorage
const useSupported: typeof import('@vueuse/core')['useSupported'] const useStorageAsync: typeof import('@vueuse/core').useStorageAsync
const useSwipe: typeof import('@vueuse/core')['useSwipe'] const useStyleTag: typeof import('@vueuse/core').useStyleTag
const useTemplateRef: typeof import('vue')['useTemplateRef'] const useSupported: typeof import('@vueuse/core').useSupported
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] const useSwipe: typeof import('@vueuse/core').useSwipe
const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] const useTemplateRef: typeof import('vue').useTemplateRef
const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] const useTemplateRefsList: typeof import('@vueuse/core').useTemplateRefsList
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] const useTextDirection: typeof import('@vueuse/core').useTextDirection
const useThrottle: typeof import('@vueuse/core')['useThrottle'] const useTextSelection: typeof import('@vueuse/core').useTextSelection
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] const useTextareaAutosize: typeof import('@vueuse/core').useTextareaAutosize
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] const useThrottle: typeof import('@vueuse/core').useThrottle
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] const useThrottleFn: typeof import('@vueuse/core').useThrottleFn
const useTimeAgoIntl: typeof import('@vueuse/core')['useTimeAgoIntl'] const useThrottledRefHistory: typeof import('@vueuse/core').useThrottledRefHistory
const useTimeout: typeof import('@vueuse/core')['useTimeout'] const useTimeAgo: typeof import('@vueuse/core').useTimeAgo
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] const useTimeAgoIntl: typeof import('@vueuse/core').useTimeAgoIntl
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] const useTimeout: typeof import('@vueuse/core').useTimeout
const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] const useTimeoutFn: typeof import('@vueuse/core').useTimeoutFn
const useTitle: typeof import('@vueuse/core')['useTitle'] const useTimeoutPoll: typeof import('@vueuse/core').useTimeoutPoll
const useToNumber: typeof import('@vueuse/core')['useToNumber'] const useTimestamp: typeof import('@vueuse/core').useTimestamp
const useToString: typeof import('@vueuse/core')['useToString'] const useTitle: typeof import('@vueuse/core').useTitle
const useToggle: typeof import('@vueuse/core')['useToggle'] const useToNumber: typeof import('@vueuse/core').useToNumber
const useTransition: typeof import('@vueuse/core')['useTransition'] const useToString: typeof import('@vueuse/core').useToString
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] const useToggle: typeof import('@vueuse/core').useToggle
const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] const useTransition: typeof import('@vueuse/core').useTransition
const useVModel: typeof import('@vueuse/core')['useVModel'] const useUrlSearchParams: typeof import('@vueuse/core').useUrlSearchParams
const useVModels: typeof import('@vueuse/core')['useVModels'] const useUserMedia: typeof import('@vueuse/core').useUserMedia
const useVibrate: typeof import('@vueuse/core')['useVibrate'] const useVModel: typeof import('@vueuse/core').useVModel
const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] const useVModels: typeof import('@vueuse/core').useVModels
const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] const useVibrate: typeof import('@vueuse/core').useVibrate
const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] const useVirtualList: typeof import('@vueuse/core').useVirtualList
const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] const useWakeLock: typeof import('@vueuse/core').useWakeLock
const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] const useWebNotification: typeof import('@vueuse/core').useWebNotification
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] const useWebSocket: typeof import('@vueuse/core').useWebSocket
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] const useWebWorker: typeof import('@vueuse/core').useWebWorker
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] const useWebWorkerFn: typeof import('@vueuse/core').useWebWorkerFn
const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] const useWindowFocus: typeof import('@vueuse/core').useWindowFocus
const watch: typeof import('vue')['watch'] const useWindowScroll: typeof import('@vueuse/core').useWindowScroll
const watchArray: typeof import('@vueuse/core')['watchArray'] const useWindowSize: typeof import('@vueuse/core').useWindowSize
const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] const watch: typeof import('vue').watch
const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] const watchArray: typeof import('@vueuse/core').watchArray
const watchDeep: typeof import('@vueuse/core')['watchDeep'] const watchAtMost: typeof import('@vueuse/core').watchAtMost
const watchEffect: typeof import('vue')['watchEffect'] const watchDebounced: typeof import('@vueuse/core').watchDebounced
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] const watchDeep: typeof import('@vueuse/core').watchDeep
const watchImmediate: typeof import('@vueuse/core')['watchImmediate'] const watchEffect: typeof import('vue').watchEffect
const watchOnce: typeof import('@vueuse/core')['watchOnce'] const watchIgnorable: typeof import('@vueuse/core').watchIgnorable
const watchPausable: typeof import('@vueuse/core')['watchPausable'] const watchImmediate: typeof import('@vueuse/core').watchImmediate
const watchPostEffect: typeof import('vue')['watchPostEffect'] const watchOnce: typeof import('@vueuse/core').watchOnce
const watchSyncEffect: typeof import('vue')['watchSyncEffect'] const watchPausable: typeof import('@vueuse/core').watchPausable
const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] const watchPostEffect: typeof import('vue').watchPostEffect
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] const watchSyncEffect: typeof import('vue').watchSyncEffect
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] const watchThrottled: typeof import('@vueuse/core').watchThrottled
const whenever: typeof import('@vueuse/core')['whenever'] const watchTriggerable: typeof import('@vueuse/core').watchTriggerable
const watchWithFilter: typeof import('@vueuse/core').watchWithFilter
const whenever: typeof import('@vueuse/core').whenever
} }
// for type re-export // for type re-export
declare global { declare global {
@@ -385,6 +387,7 @@ declare module 'vue' {
readonly debouncedWatch: UnwrapRef<typeof import('@vueuse/core')['debouncedWatch']> readonly debouncedWatch: UnwrapRef<typeof import('@vueuse/core')['debouncedWatch']>
readonly deepFreeze: UnwrapRef<typeof import('deep-freeze-es6')['default']> readonly deepFreeze: UnwrapRef<typeof import('deep-freeze-es6')['default']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']> readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineBasicLoader: UnwrapRef<typeof import('unplugin-vue-router/data-loaders/basic')['defineBasicLoader']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']> readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']> readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
readonly eagerComputed: UnwrapRef<typeof import('@vueuse/core')['eagerComputed']> readonly eagerComputed: UnwrapRef<typeof import('@vueuse/core')['eagerComputed']>
@@ -449,11 +452,13 @@ declare module 'vue' {
readonly refAutoReset: UnwrapRef<typeof import('@vueuse/core')['refAutoReset']> readonly refAutoReset: UnwrapRef<typeof import('@vueuse/core')['refAutoReset']>
readonly refDebounced: UnwrapRef<typeof import('@vueuse/core')['refDebounced']> readonly refDebounced: UnwrapRef<typeof import('@vueuse/core')['refDebounced']>
readonly refDefault: UnwrapRef<typeof import('@vueuse/core')['refDefault']> readonly refDefault: UnwrapRef<typeof import('@vueuse/core')['refDefault']>
readonly refManualReset: UnwrapRef<typeof import('@vueuse/core')['refManualReset']>
readonly refThrottled: UnwrapRef<typeof import('@vueuse/core')['refThrottled']> readonly refThrottled: UnwrapRef<typeof import('@vueuse/core')['refThrottled']>
readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']> readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']> readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']> readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']> readonly routeI18nInstance: UnwrapRef<typeof import('./src/locales-utils/i18n-auto-imports')['routeI18nInstance']>
readonly routeI18nT: UnwrapRef<typeof import('./src/locales-utils/i18n-auto-imports')['routeI18nT']>
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']> readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']> readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
readonly setViewportCSSVars: UnwrapRef<typeof import('utils4u/browser')['setViewportCSSVars']> readonly setViewportCSSVars: UnwrapRef<typeof import('utils4u/browser')['setViewportCSSVars']>
@@ -499,6 +504,7 @@ declare module 'vue' {
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']> readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']> readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']> readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useAuthStore: UnwrapRef<typeof import('./src/stores/auth-store-auto-imports')['useAuthStore']>
readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']> readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']>
readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']> readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']>
readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']> readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']>
@@ -561,7 +567,6 @@ declare module 'vue' {
readonly useIntervalFn: UnwrapRef<typeof import('@vueuse/core')['useIntervalFn']> readonly useIntervalFn: UnwrapRef<typeof import('@vueuse/core')['useIntervalFn']>
readonly useKeyModifier: UnwrapRef<typeof import('@vueuse/core')['useKeyModifier']> readonly useKeyModifier: UnwrapRef<typeof import('@vueuse/core')['useKeyModifier']>
readonly useLastChanged: UnwrapRef<typeof import('@vueuse/core')['useLastChanged']> readonly useLastChanged: UnwrapRef<typeof import('@vueuse/core')['useLastChanged']>
readonly useLink: UnwrapRef<typeof import('vue-router/auto')['useLink']>
readonly useLoadingBar: UnwrapRef<typeof import('naive-ui')['useLoadingBar']> readonly useLoadingBar: UnwrapRef<typeof import('naive-ui')['useLoadingBar']>
readonly useLocalStorage: UnwrapRef<typeof import('@vueuse/core')['useLocalStorage']> readonly useLocalStorage: UnwrapRef<typeof import('@vueuse/core')['useLocalStorage']>
readonly useMagicKeys: UnwrapRef<typeof import('@vueuse/core')['useMagicKeys']> readonly useMagicKeys: UnwrapRef<typeof import('@vueuse/core')['useMagicKeys']>
@@ -609,7 +614,6 @@ declare module 'vue' {
readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']> readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']> readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
readonly useSSRWidth: UnwrapRef<typeof import('@vueuse/core')['useSSRWidth']> readonly useSSRWidth: UnwrapRef<typeof import('@vueuse/core')['useSSRWidth']>
readonly useSafeNForm: UnwrapRef<typeof import('./src/utils/use-safe-n-form-auto-imports')['useSafeNForm']>
readonly useScreenOrientation: UnwrapRef<typeof import('@vueuse/core')['useScreenOrientation']> readonly useScreenOrientation: UnwrapRef<typeof import('@vueuse/core')['useScreenOrientation']>
readonly useScreenSafeArea: UnwrapRef<typeof import('@vueuse/core')['useScreenSafeArea']> readonly useScreenSafeArea: UnwrapRef<typeof import('@vueuse/core')['useScreenSafeArea']>
readonly useScriptTag: UnwrapRef<typeof import('@vueuse/core')['useScriptTag']> readonly useScriptTag: UnwrapRef<typeof import('@vueuse/core')['useScriptTag']>

View File

@@ -1,9 +1,11 @@
import type { UserConfig } from '@commitlint/types'; import type { UserConfig } from '@commitlint/types';
const Configuration: UserConfig = { const Configuration: UserConfig = {
extends: ['@commitlint/config-conventional'], extends: ['@commitlint/config-conventional'],
formatter: '@commitlint/format', formatter: '@commitlint/format',
rules: {
'body-max-line-length': [2, 'always', 500],
},
}; };
export default Configuration; export default Configuration;

View File

@@ -1,4 +1,4 @@
{ {
"extends": "@tsconfig/node22/tsconfig.json", "extends": "@tsconfig/node24/tsconfig.json",
"include": ["./**/*"] "include": ["./**/*"]
} }

View File

@@ -1,15 +1,20 @@
import pluginImport from 'eslint-plugin-import'; import vueI18n from '@intlify/eslint-plugin-vue-i18n';
import { globalIgnores } from 'eslint/config'; // import stylistic from '@stylistic/eslint-plugin';
import pluginVitest from '@vitest/eslint-plugin';
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';
import { import {
configureVueProject,
defineConfigWithVueTs, defineConfigWithVueTs,
vueTsConfigs, vueTsConfigs,
configureVueProject,
} from '@vue/eslint-config-typescript'; } from '@vue/eslint-config-typescript';
import pluginVue from 'eslint-plugin-vue'; import pluginImport from 'eslint-plugin-import';
import pluginVitest from '@vitest/eslint-plugin'; import pluginJsonc from 'eslint-plugin-jsonc';
import pluginPlaywright from 'eslint-plugin-playwright';
import pluginOxlint from 'eslint-plugin-oxlint'; import pluginOxlint from 'eslint-plugin-oxlint';
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'; import pluginPerfectionist from 'eslint-plugin-perfectionist';
import pluginPlaywright from 'eslint-plugin-playwright';
import pluginVue from 'eslint-plugin-vue';
import { globalIgnores } from 'eslint/config';
import jsoncParser from 'jsonc-eslint-parser';
configureVueProject({ scriptLangs: ['ts', 'tsx'] }); configureVueProject({ scriptLangs: ['ts', 'tsx'] });
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup // More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
@@ -20,7 +25,14 @@ export default defineConfigWithVueTs(
files: ['**/*.{ts,mts,tsx,vue}'], files: ['**/*.{ts,mts,tsx,vue}'],
}, },
globalIgnores(['worker-configuration.d.ts', '**/dist/**', '**/dist-ssr/**', '**/coverage/**']), globalIgnores([
'worker-configuration.d.ts',
'**/dist/**',
'**/dist-ssr/**',
'**/coverage/**',
'**/public/**',
'**/-----TEMP-----/**',
]),
pluginVue.configs['flat/essential'], pluginVue.configs['flat/essential'],
vueTsConfigs.recommended, vueTsConfigs.recommended,
@@ -35,10 +47,29 @@ export default defineConfigWithVueTs(
files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'], files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'],
}, },
...pluginOxlint.configs['flat/recommended'], ...pluginOxlint.configs['flat/recommended'],
// https://eslint-plugin-vue-i18n.intlify.dev/started.html#getting-started
...vueI18n.configs.recommended,
{ {
plugins: { rules: {
import: pluginImport, '@intlify/vue-i18n/no-raw-text': 'off',
'@intlify/vue-i18n/no-unused-keys': [
'error',
{
src: './src',
extensions: ['.js', '.ts', '.tsx', '.vue'],
},
],
}, },
settings: {
'vue-i18n': {
localeDir: './src/locales/**/*.json',
messageSyntaxVersion: '^11.0.0',
},
},
},
{
plugins: { import: pluginImport },
rules: { rules: {
'import/first': 'error', 'import/first': 'error',
'import/no-duplicates': 'error', 'import/no-duplicates': 'error',
@@ -52,7 +83,25 @@ export default defineConfigWithVueTs(
}, },
}, },
{ plugins: { perfectionist: pluginPerfectionist } },
{ {
/**
* 启用 sort-keys 规则以强制对象键按字母顺序排序
* 原因:
* 1. 减少多人协作时的合并冲突
* 2. 保持代码一致性,提高可维护性
*/
files: ['src/locales/**/*.json'],
languageOptions: { parser: jsoncParser },
plugins: { jsonc: pluginJsonc },
rules: { 'jsonc/sort-keys': 'error' },
},
{
// plugins: {
// '@stylistic': stylistic,
// },
rules: { rules: {
'@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-explicit-any': 'off',
'vue/block-order': [ 'vue/block-order': [
@@ -67,6 +116,18 @@ export default defineConfigWithVueTs(
], ],
'vue/attributes-order': 'error', 'vue/attributes-order': 'error',
'vue/multi-word-component-names': 'off', 'vue/multi-word-component-names': 'off',
'vue/padding-line-between-blocks': ['error', 'always'],
'vue/component-name-in-template-casing': [
'error',
'PascalCase',
{ registeredComponentsOnly: false, ignores: [] },
],
// '@stylistic/padding-line-between-statements': [
// 'error',
// { blankLine: 'always', prev: '*', next: ['const', 'let', 'var'] },
// { blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },
// { blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] },
// ],
}, },
}, },

View File

@@ -11,40 +11,6 @@
name="viewport" name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/> />
<script>
window.addEventListener('DOMContentLoaded', function () {
window.ontouchstart = function () {};
window.ontouchend = function () {};
});
window.onloadX = function () {
// 禁止双指缩放
document.addEventListener('touchstart', function (event) {
if (event.touches.length > 1) {
event.preventDefault();
}
});
// 禁止双击放大
var lastTouchEnd = 0;
document.addEventListener(
'touchend',
function (event) {
var now = new Date().getTime();
if (now - lastTouchEnd <= 300) {
event.preventDefault();
}
lastTouchEnd = now;
},
false,
);
// 禁止手势事件
document.addEventListener('gesturestart', function (event) {
event.preventDefault();
});
};
</script>
<meta name="color-scheme" content="light dark" /> <meta name="color-scheme" content="light dark" />
<meta name="format-detection" content="telephone=no" /> <meta name="format-detection" content="telephone=no" />
@@ -132,35 +98,69 @@
<!-- <script src="https://testingcf.jsdelivr.net/npm/@vant/touch-emulator/dist/index.min.js"></script> --> <!-- <script src="https://testingcf.jsdelivr.net/npm/@vant/touch-emulator/dist/index.min.js"></script> -->
<!-- .min.js 是 jsDelivr 的特殊处理 --> <!-- .min.js 是 jsDelivr 的特殊处理 -->
<!-- <script src="https://unpkg.luckincdn.com/@vant/touch-emulator@1.4.0/dist/index.js"></script> --> <!-- <script src="https://unpkg.luckincdn.com/@vant/touch-emulator@1.4.0/dist/index.js"></script> -->
</body> <script>
<script> window.addEventListener('DOMContentLoaded', function () {
(function (d) { window.ontouchstart = function () {};
var config = { window.ontouchend = function () {};
kitId: 'whk2tto', });
scriptTimeout: 3000,
async: true, window.onloadX = function () {
}, // 禁止双指缩放
h = d.documentElement, document.addEventListener('touchstart', function (event) {
t = setTimeout(function () { if (event.touches.length > 1) {
h.className = h.className.replace(/\bwf-loading\b/g, '') + ' wf-inactive'; event.preventDefault();
}, config.scriptTimeout), }
tk = d.createElement('script'), });
f = false,
s = d.getElementsByTagName('script')[0], // 禁止双击放大
a; var lastTouchEnd = 0;
h.className += ' wf-loading'; document.addEventListener(
tk.src = 'https://use.typekit.net/' + config.kitId + '.js'; 'touchend',
tk.async = true; function (event) {
tk.onload = tk.onreadystatechange = function () { var now = new Date().getTime();
a = this.readyState; if (now - lastTouchEnd <= 300) {
if (f || (a && a != 'complete' && a != 'loaded')) return; event.preventDefault();
f = true; }
clearTimeout(t); lastTouchEnd = now;
try { },
Typekit.load(config); false,
} catch (e) {} );
// 禁止手势事件
document.addEventListener('gesturestart', function (event) {
event.preventDefault();
});
}; };
s.parentNode.insertBefore(tk, s); </script>
}); /* (document) */ <script>
</script> (function (d) {
var config = {
kitId: 'whk2tto',
scriptTimeout: 3000,
async: true,
},
h = d.documentElement,
t = setTimeout(function () {
h.className = h.className.replace(/\bwf-loading\b/g, '') + ' wf-inactive';
}, config.scriptTimeout),
tk = d.createElement('script'),
f = false,
s = d.getElementsByTagName('script')[0],
a;
h.className += ' wf-loading';
tk.src = 'https://use.typekit.net/' + config.kitId + '.js';
tk.async = true;
tk.onload = tk.onreadystatechange = function () {
a = this.readyState;
if (f || (a && a != 'complete' && a != 'loaded')) return;
f = true;
clearTimeout(t);
try {
Typekit.load(config);
} catch (e) {}
};
s.parentNode.insertBefore(tk, s);
}); /* (document) */
</script>
</body>
</html> </html>

View File

@@ -1,28 +1,34 @@
{ {
"packageManager": "pnpm@10.18.3", "packageManager": "pnpm@10.25.0",
"name": "vue-ts-example-2025", "name": "vue-ts-example-2025",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"engines": { "_devenginesruntime_docs": "https://pnpm.io/zh/package_json#devenginesruntime",
"node": "^20.19.0 || >=22.12.0" "devEngines": {
"runtime": {
"name": "node",
"version": "^24.11.1",
"onFail": "download"
}
}, },
"scripts": { "scripts": {
"_all": "run-s build-only lint format:prettier type-check test:unit:DisableWatch", "all": "run-s lint format:prettier build-only type-check test:unit:DisableWatch",
"dev": "vite --port 4730 --host --strictPort", "dev": "nodemon --delay 280ms --watch vite-plugins --ext ts -x vite -- --port 4730 --host --strictPort",
"build": "run-p type-check \"build-only {@}\" --", "build": "run-p type-check \"build-only {@}\" --",
"build-only": "vite build", "build-only": "vite build",
"preview": "vite preview --port 4731 --host --strictPort", "preview": "vite preview --port 4731 --host --strictPort",
"wrangler:dev": "wrangler dev --port 4732", "wrangler:dev": "wrangler dev --port 4732",
"format:prettier": "prettier --write src/", "format:prettier": "prettier --config=.prettierrc.json --cache --write --log-level=warn src/",
"type-check": "vue-tsc --build", "type-check": "vue-tsc --build",
"lint": "run-s lint:*", "lint": "run-s lint:*",
"lint:vue-i18n-extract": "vue-i18n-extract report --vueFiles './src/**/*.?(ts|tsx|vue)' --languageFiles './src/locales/**/*.?(json|yml|yaml|js)' --ci", "lint:vue-i18n-extract": "vue-i18n-extract report --vueFiles './src/**/*.?(ts|tsx|vue)' --languageFiles './src/locales/**/*.?(json|yml|yaml|js)' --ci",
"lint:stylelint": "stylelint --fix --ignore-path .gitignore \"**/*.{css,less,scss,vue}\"", "lint:stylelint": "stylelint --config=stylelint.config.mjs --cache --output-file=node_modules/.cache/stylelint/stylelint-report.json --cache-location=node_modules/.cache/stylelint/.stylelintcache --fix --ignore-path=.gitignore '**/*.{css,less,scss,vue}'",
"lint:oxlint": "oxlint . --fix -D correctness --ignore-path .gitignore", "lint:oxlint": "oxlint . --fix -D correctness --ignore-path .gitignore",
"lint:eslint": "eslint . --fix", "lint:eslint": "eslint . --fix --config=eslint.config.ts --concurrency=auto --env-info --cache --cache-location=node_modules/.cache/eslint/.eslintcache",
"test:unit:DisableWatch": "vitest --run", "test:unit:DisableWatch": "vitest --run",
"test:playwright:headless": "HEADLESS=true playwright test --quiet", "test:playwright:headless": "HEADLESS=true playwright test --quiet",
"_stylelint-config": "stylelint --config=stylelint.config.mjs --print-config src/styles/scss/global.scss",
"postinstall": "wrangler types", "postinstall": "wrangler types",
"prepare": "husky" "prepare": "husky"
}, },
@@ -38,9 +44,6 @@
"{src/locales-utils,src/locales}/**/*": "node scripts/type-check-for-lint-staged.mjs" "{src/locales-utils,src/locales}/**/*": "node scripts/type-check-for-lint-staged.mjs"
}, },
"pnpm": { "pnpm": {
"overrides": {
"vue-tsc": "$vue-tsc"
},
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
"@parcel/watcher", "@parcel/watcher",
"esbuild", "esbuild",
@@ -51,102 +54,110 @@
] ]
}, },
"dependencies": { "dependencies": {
"@commitlint/cli": "^20.0.0", "@commitlint/cli": "^20.1.0",
"@commitlint/config-conventional": "^20.0.0", "@commitlint/config-conventional": "^20.0.0",
"@formkit/auto-animate": "^0.9.0", "@formkit/auto-animate": "^0.9.0",
"@pinia/colada": "^0.17.4", "@pinia/colada": "^0.21.0",
"@primeuix/themes": "^1.2.3", "@primeuix/themes": "^2.0.0",
"@sa/materials": "workspace:*", "@sa/materials": "workspace:*",
"@unhead/vue": "^2.0.14", "@unhead/vue": "^2.0.19",
"@vueuse/core": "^13.9.0", "@vueuse/core": "^14.0.0",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"jsonc-eslint-parser": "^2.4.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"naive-ui": "^2.43.1", "naive-ui": "^2.43.2",
"pinia": "^3.0.3", "pinia": "^3.0.4",
"primeicons": "^7.0.0", "primeicons": "^7.0.0",
"primelocale": "^2.1.7", "primelocale": "^2.2.2",
"primevue": "^4.3.9", "primevue": "^4.4.1",
"ts-enum-util": "^4.1.0", "ts-enum-util": "^4.1.0",
"utils4u": "^4.2.3", "utils4u": "^5",
"vue": "^3.5.21", "vue": "^3.5.24",
"vue-i18n": "^11.1.12", "vue-i18n": "^11.2.1",
"vue-memoize-dict": "^1.1.3", "vue-memoize-dict": "^1.1.3",
"vue-router": "^4.6.3" "vue-router": "^4.6.3"
}, },
"devDependencies": { "devDependencies": {
"@cloudflare/vite-plugin": "^1.13.2", "@cloudflare/vite-plugin": "^1.15.2",
"@commitlint/types": "^20.0.0", "@commitlint/types": "^20.0.0",
"@iconify-json/carbon": "^1.2.13", "@iconify-json/carbon": "^1.2.14",
"@iconify-json/clarity": "^1.2.4", "@iconify-json/clarity": "^1.2.4",
"@iconify-json/line-md": "^1.2.11", "@iconify-json/line-md": "^1.2.11",
"@iconify-json/material-symbols": "^1.2.42", "@iconify-json/material-symbols": "^1.2.47",
"@intlify/unplugin-vue-i18n": "^11.0.0", "@intlify/eslint-plugin-vue-i18n": "^4.1.0",
"@playwright/test": "^1.55.0", "@intlify/unplugin-vue-i18n": "^11.0.1",
"@prettier/plugin-oxc": "^0.0.4", "@playwright/test": "^1.57.0",
"@primevue/auto-import-resolver": "^4.3.9", "@prettier/plugin-oxc": "^0.1.3",
"@primevue/metadata": "^4.3.9", "@primevue/auto-import-resolver": "^4.4.1",
"@primevue/metadata": "^4.4.1",
"@stylelint-types/stylelint-order": "^7.0.0", "@stylelint-types/stylelint-order": "^7.0.0",
"@stylelint-types/stylelint-scss": "^6.11.0", "@stylelint-types/stylelint-scss": "^6.11.0",
"@tsconfig/node22": "^22.0.2", "@stylistic/eslint-plugin": "^5.6.1",
"@tsconfig/node24": "^24.0.0",
"@types/html-minifier-terser": "^7.0.2", "@types/html-minifier-terser": "^7.0.2",
"@types/jsdom": "^27.0.0", "@types/jsdom": "^27.0.0",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^22.18.1", "@types/node": "^24.10.1",
"@vant/auto-import-resolver": "^1.3.0", "@vant/auto-import-resolver": "^1.3.0",
"@vitejs/plugin-vue": "^6.0.1", "@vitejs/plugin-vue": "^6.0.2",
"@vitejs/plugin-vue-jsx": "^5.1.1", "@vitejs/plugin-vue-jsx": "^5.1.2",
"@vitest/eslint-plugin": "^1.3.9", "@vitest/eslint-plugin": "^1.4.3",
"@vue/eslint-config-prettier": "^10.2.0", "@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.6.0", "@vue/eslint-config-typescript": "^14.6.0",
"@vue/test-utils": "^2.4.6", "@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.8.1", "@vue/tsconfig": "^0.8.1",
"boxen": "^8.0.1",
"consola": "^3.4.2", "consola": "^3.4.2",
"eslint": "^9.35.0", "eslint": "^9.39.1",
"eslint-plugin-import": "^2.32.0", "eslint-plugin-import": "^2.32.0",
"eslint-plugin-oxlint": "~1.23.0", "eslint-plugin-jsonc": "^2.21.0",
"eslint-plugin-playwright": "^2.2.2", "eslint-plugin-oxlint": "~1.32.0",
"eslint-plugin-vue": "~10.5.0", "eslint-plugin-perfectionist": "^5.0.0",
"happy-dom": "^20.0.1", "eslint-plugin-playwright": "^2.3.0",
"eslint-plugin-vue": "~10.6.0",
"happy-dom": "^20.0.10",
"html-minifier-terser": "^7.2.0", "html-minifier-terser": "^7.2.0",
"husky": "^9.1.7", "husky": "^9.1.7",
"jsdom": "^27.0.0", "jsdom": "^27.2.0",
"lint-staged": "^16.1.6", "lint-staged": "^16.2.7",
"nodemon": "^3.1.11",
"npm-run-all2": "^8.0.4", "npm-run-all2": "^8.0.4",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"oxlint": "~1.23.0", "oxlint": "~1.29.0",
"postcss-html": "^1.8.0", "postcss-html": "^1.8.0",
"prettier": "3.6.2", "prettier": "3.7.4",
"rollup": "^4.52.5", "rollup": "^4.53.3",
"sass-embedded": "^1.93.2", "sass-embedded": "^1.93.3",
"stylelint": "^16.25.0", "sharp": "^0.34.5",
"stylelint-config-recess-order": "^7.3.0", "stylelint": "^16.26.0",
"stylelint-config-recess-order": "^7.4.0",
"stylelint-config-standard": "^39.0.1", "stylelint-config-standard": "^39.0.1",
"stylelint-config-standard-scss": "^16.0.0", "stylelint-config-standard-scss": "^16.0.0",
"stylelint-config-standard-vue": "^1.0.0", "stylelint-config-standard-vue": "^1.0.0",
"stylelint-define-config": "^16.24.0", "stylelint-define-config": "^16.24.0",
"svgo": "^4.0.0", "svgo": "^4.0.0",
"tinyglobby": "^0.2.15", "tinyglobby": "^0.2.15",
"type-fest": "^5.1.0", "type-fest": "^5.2.0",
"typescript": "~5.9.2", "typescript": "~5.9.3",
"unocss": "^66.5.1", "unocss": "^66.5.9",
"unocss-preset-animations": "^1.2.1", "unocss-preset-animations": "^1.3.0",
"unplugin-auto-import": "^20.1.0", "unplugin-auto-import": "^20.2.0",
"unplugin-icons": "^22.2.0", "unplugin-icons": "^22.5.0",
"unplugin-vue-components": "^29.2.0", "unplugin-vue-components": "^30.0.0",
"unplugin-vue-markdown": "^29.2.0", "unplugin-vue-markdown": "^29.2.0",
"unplugin-vue-router": "^0.16.0", "unplugin-vue-router": "^0.19.0",
"vite": "^7.1.5", "vite": "^7.2.4",
"vite-plugin-checker": "^0.11.0", "vite-plugin-checker": "^0.12.0",
"vite-plugin-fake-server": "^2.2.0", "vite-plugin-fake-server": "^2.2.2",
"vite-plugin-image-optimizer": "^2.0.2", "vite-plugin-image-optimizer": "^2.0.3",
"vite-plugin-vue-devtools": "^8.0.1", "vite-plugin-vue-devtools": "^8.0.5",
"vite-plugin-vue-meta-layouts": "^0.6.1", "vite-plugin-vue-meta-layouts": "^0.6.1",
"vite-plugin-webfont-dl": "^3.11.1", "vite-plugin-webfont-dl": "^3.11.1",
"vitest": "^3.2.4", "vitest": "^4.0.13",
"vue-component-type-helpers": "^3.1.2", "vue-component-type-helpers": "^3.1.4",
"vue-i18n-extract": "^2.0.7", "vue-i18n-extract": "^2.0.7",
"vue-macros": "3.1.1", "vue-macros": "3.1.2",
"vue-tsc": "^3.1.0", "vue-tsc": "^3.1.8",
"wrangler": "^4.37.1" "wrangler": "^4.50.0"
} }
} }

6230
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +1,6 @@
packages: packages:
- "packages/*" - 'packages/*'
# shamefullyHoist: false # https://pnpm.io/zh/settings#shamefullyhoist
overrides:
vue-tsc: $vue-tsc

View File

@@ -1,16 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { RouterView } from 'vue-router';
import AppNaiveUIProvider from './AppNaiveUIProvider.vue'; import AppNaiveUIProvider from './AppNaiveUIProvider.vue';
import A2use from './utils/a2use.vue';
</script> </script>
<template> <template>
<DynamicDialog /> <DynamicDialog />
<ConfirmDialog /> <ConfirmDialog />
<Toast /> <Toast style="z-index: 5000" />
<AppNaiveUIProvider> <AppNaiveUIProvider>
<!-- <RouterView /> --> <RouterView v-slot="{ Component }">
<Transition name="fade" mode="out-in">
<A2use></A2use> <component :is="Component" />
</Transition>
</RouterView>
</AppNaiveUIProvider> </AppNaiveUIProvider>
</template> </template>

View File

@@ -42,17 +42,17 @@ declare global {
:theme="appStore.isDark ? darkTheme : null" :theme="appStore.isDark ? darkTheme : null"
abstract abstract
> >
<n-loading-bar-provider> <NLoadingBarProvider>
<n-message-provider> <NMessageProvider>
<n-notification-provider> <NNotificationProvider>
<n-modal-provider> <NModalProvider>
<n-dialog-provider> <NDialogProvider>
<slot></slot> <slot></slot>
<ContextHolder /> <ContextHolder />
</n-dialog-provider> </NDialogProvider>
</n-modal-provider> </NModalProvider>
</n-notification-provider> </NNotificationProvider>
</n-message-provider> </NMessageProvider>
</n-loading-bar-provider> </NLoadingBarProvider>
</NConfigProvider> </NConfigProvider>
</template> </template>

View File

@@ -8,16 +8,7 @@ import IconMenuRounded from '~icons/material-symbols/menu-rounded';
export function useMetaLayoutsNMenuOptions({ menuInstRef }: { menuInstRef: Ref<MenuInst | null> }) { export function useMetaLayoutsNMenuOptions({ menuInstRef }: { menuInstRef: Ref<MenuInst | null> }) {
const router = useRouter(); const router = useRouter();
const { t, te } = useI18n({ const { t, te } = routeI18nInstance.global;
inheritLocale: true,
useScope: 'local',
missing: (locale, key) => {
consola.warn(`菜单翻译缺失: locale=${locale}, key=${key}`);
return key;
},
fallbackRoot: true,
messages: i18nRouteMessages,
});
// 获取路由表但是不包含布局路由 // 获取路由表但是不包含布局路由
const routes = createGetRoutes(router)(); const routes = createGetRoutes(router)();
@@ -26,10 +17,15 @@ export function useMetaLayoutsNMenuOptions({ menuInstRef }: { menuInstRef: Ref<M
const selectedKey = ref(''); const selectedKey = ref('');
watch( watch(
() => router.currentRoute.value.path, () => router.currentRoute.value,
(newPath) => { (route) => {
selectedKey.value = newPath; // 优先使用 activeMenuName通过路由名称解析为路径如果没有则使用当前路径
menuInstRef.value?.showOption(newPath); // 展开菜单,确保设定的元素被显示,如果不传入 key 会展示当前选中元素 const activeMenuPath = route.meta.activeMenuName
? router.resolve({ name: route.meta.activeMenuName }).path
: route.path;
selectedKey.value = activeMenuPath;
menuInstRef.value?.showOption(activeMenuPath); // 展开菜单,确保设定的元素被显示
}, },
{ immediate: true }, { immediate: true },
); );
@@ -113,7 +109,7 @@ export function useMetaLayoutsNMenuOptions({ menuInstRef }: { menuInstRef: Ref<M
const pathSegments = route.path.split('/').filter(Boolean); const pathSegments = route.path.split('/').filter(Boolean);
const routeName = route.name as string; const routeName = route.name as string;
let text = te(routeName) ? t(routeName) : route.meta?.title || routeName; let text = te(routeName) ? t(routeName) : routeName;
if (import.meta.env.VITE_APP_MENU_SHOW_ORDER === 'true' && route.meta?.order) { if (import.meta.env.VITE_APP_MENU_SHOW_ORDER === 'true' && route.meta?.order) {
const order = String(route.meta.order).padStart(orderMaxLength, '0'); const order = String(route.meta.order).padStart(orderMaxLength, '0');
text = `${order}. ${text}`; text = `${order}. ${text}`;

View File

@@ -2,6 +2,7 @@
import LanguageSwitchButton from './components/LanguageSwitchButton.vue'; import LanguageSwitchButton from './components/LanguageSwitchButton.vue';
import ThemeSwitchButton from './components/ThemeSwitchButton.vue'; import ThemeSwitchButton from './components/ThemeSwitchButton.vue';
import ToggleSiderButton from './components/ToggleSiderButton.vue'; import ToggleSiderButton from './components/ToggleSiderButton.vue';
import UserDropdown from './components/UserDropdown.vue';
</script> </script>
<template> <template>
@@ -11,6 +12,7 @@ import ToggleSiderButton from './components/ToggleSiderButton.vue';
<div class="flex items-center"> <div class="flex items-center">
<LanguageSwitchButton /> <LanguageSwitchButton />
<ThemeSwitchButton /> <ThemeSwitchButton />
<UserDropdown />
</div> </div>
</div> </div>
</template> </template>

View File

@@ -25,7 +25,7 @@ function handleSelect(key: string) {
<NDropdown trigger="hover" placement="bottom-end" :options="options" @select="handleSelect"> <NDropdown trigger="hover" placement="bottom-end" :options="options" @select="handleSelect">
<NButton quaternary class="flex items-center gap-1"> <NButton quaternary class="flex items-center gap-1">
<template #icon> <template #icon>
<icon-clarity-language-line w-4.5 h-4.5 /> <IconClarityLanguageLine w-4.5 h-4.5 />
</template> </template>
<span>{{ languageLabels[locale] }}</span> <span>{{ languageLabels[locale] }}</span>
</NButton> </NButton>

View File

@@ -13,17 +13,17 @@ const themeLabels: Record<AppThemeMode, string> = {
{{ themeLabels[appStore.themeMode] }} {{ themeLabels[appStore.themeMode] }}
<template #trigger> <template #trigger>
<NButton quaternary @click="appStore.cycleTheme()"> <NButton quaternary @click="appStore.cycleTheme()">
<icon-line-md-sunny-filled-loop-to-moon-filled-loop-transition <IconLineMdSunnyFilledLoopToMoonFilledLoopTransition
v-if="appStore.themeMode === 'light'" v-if="appStore.themeMode === 'light'"
w-4.5 w-4.5
h-4.5 h-4.5
/> />
<icon-line-md-moon-filled-to-sunny-filled-loop-transition <IconLineMdMoonFilledToSunnyFilledLoopTransition
v-else-if="appStore.themeMode === 'dark'" v-else-if="appStore.themeMode === 'dark'"
w-4.5 w-4.5
h-4.5 h-4.5
/> />
<icon-line-md-computer v-else w-4.5 h-4.5 /> <IconLineMdComputer v-else w-4.5 h-4.5 />
</NButton> </NButton>
</template> </template>
</NTooltip> </NTooltip>

View File

@@ -15,8 +15,8 @@ function toggleCollapsed() {
{{ appStore.sidebarCollapsed ? '展开菜单' : '收起菜单' }} {{ appStore.sidebarCollapsed ? '展开菜单' : '收起菜单' }}
<template #trigger> <template #trigger>
<NButton ref="buttonRef" quaternary @click="toggleCollapsed"> <NButton ref="buttonRef" quaternary @click="toggleCollapsed">
<icon-line-md-menu-fold-right v-if="appStore.sidebarCollapsed" w-4.5 h-4.5 /> <IconLineMdMenuFoldRight v-if="appStore.sidebarCollapsed" w-4.5 h-4.5 />
<icon-line-md-menu-fold-left v-else w-4.5 h-4.5 /> <IconLineMdMenuFoldLeft v-else w-4.5 h-4.5 />
</NButton> </NButton>
</template> </template>
</NTooltip> </NTooltip>

View File

@@ -0,0 +1,45 @@
<script setup lang="tsx">
const router = useRouter();
const userStore = useAuthStore();
const dialog = useDialog();
const options = computed(() => [
{
label: userStore.userInfo?.nickname || userStore.userInfo?.username || '用户',
key: 'user',
disabled: true,
},
{
type: 'divider',
key: 'd1',
},
{
label: '退出登录',
key: 'logout',
icon: () => <icon-material-symbols-logout class="w-4 h-4" />,
},
]);
function handleSelect(key: string) {
if (key === 'logout') {
dialog.warning({
title: '退出登录',
content: '确定要退出登录吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
userStore.clearToken('用户退出登录');
router.push('/login');
},
});
}
}
</script>
<template>
<NDropdown :options="options" placement="bottom-end" @select="handleSelect">
<NButton quaternary circle>
<IconMaterialSymbolsAccountCircle w-5 h-5 />
</NButton>
</NDropdown>
</template>

View File

@@ -29,11 +29,11 @@ const appStore = useAppStore();
<BaseLayoutSider /> <BaseLayoutSider />
</template> </template>
<!-- <div>GlobalContent</div> --> <!-- <div>GlobalContent</div> -->
<router-view v-slot="{ Component }"> <RouterView v-slot="{ Component }">
<transition name="fade" mode="out-in"> <Transition name="fade" mode="out-in">
<component :is="Component" /> <component :is="Component" />
</transition> </Transition>
</router-view> </RouterView>
<!-- <div>ThemeDrawer</div> --> <!-- <div>ThemeDrawer</div> -->
<template #footer> <template #footer>
<div <div
@@ -49,14 +49,4 @@ const appStore = useAppStore();
#__SCROLL_EL_ID__ { #__SCROLL_EL_ID__ {
@include scrollbar; @include scrollbar;
} }
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.25s ease-in-out;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style> </style>

View File

@@ -4,7 +4,10 @@
*/ */
import messages from '@intlify/unplugin-vue-i18n/messages'; import messages from '@intlify/unplugin-vue-i18n/messages';
import { router } from '@/plugins/00.router-plugin';
import { createGetRoutes } from 'virtual:meta-layouts';
import { createI18n } from 'vue-i18n'; import { createI18n } from 'vue-i18n';
import { START_LOCATION } from 'vue-router';
const locale = useLocalStorage<string>('app-locale', navigator.language); const locale = useLocalStorage<string>('app-locale', navigator.language);
watchEffect(() => { watchEffect(() => {
@@ -26,6 +29,52 @@ export const i18nInstance = createI18n({
messages, messages,
}); });
watchEffect(() => { export const routeI18nInstance = createI18n({
locale.value = i18nInstance.global.locale.value; legacy: false, // you must set `false`, to use Composition API
locale: locale.value,
inheritLocale: true,
useScope: 'local',
missing: (locale, key) => {
consola.warn(`菜单翻译缺失: locale=${locale}, key=${key}`);
if (__DEV__) {
ToastService.add({
severity: 'warn',
summary: '菜单翻译缺失',
detail: `菜单翻译缺失: locale=${locale}, key=${key}`,
life: 5000,
});
}
return key;
},
fallbackRoot: true,
messages: i18nRouteMessages,
}); });
export const routeI18nT = routeI18nInstance.global.t;
watchEffect(
() => {
locale.value = i18nInstance.global.locale.value;
},
{ flush: 'sync' },
);
watch(
() => i18nInstance.global.locale.value,
() => {
const { t, te } = routeI18nInstance.global;
routeI18nInstance.global.locale.value = i18nInstance.global.locale.value;
if (router.currentRoute.value.name && router.currentRoute.value !== START_LOCATION) {
router.currentRoute.value.meta.title = t(router.currentRoute.value.name as string);
}
const routes = createGetRoutes(router)(); // 获取路由表但是不包含布局路由
routes.forEach((route) => {
const routeName = route.name as string;
route.meta.title = te(routeName) ? t(routeName) : routeName;
});
},
{ immediate: true, flush: 'sync' },
);

View File

@@ -1,13 +1,25 @@
/*eslint perfectionist/sort-objects: "error"*/
/**
* 启用 perfectionist/sort-objects 规则以强制对象键按字母顺序排序
* 原因:
* 1. 减少多人协作时的合并冲突
* 2. 保持代码一致性,提高可维护性
*
* 运行以下命令自动修复排序:
* pnpm exec eslint --fix --no-ignore src/locales-utils/route-messages/
*/
export default { export default {
Root: 'Index',
$Path: '$Path', $Path: '$Path',
Demos: 'Demos', Demos: 'Demos',
DemosApiDemo: 'API Demo', DemosApiDemo: 'API Demo',
DemosCounterDemo: 'Counter Demo', DemosCounterDemo: 'Counter Demo',
DemosCreate: 'Create Demo',
DemosI18nDemo: 'i18n Demo', DemosI18nDemo: 'i18n Demo',
DemosNaiveUiDemo: 'Naive UI Demo', DemosNaiveUiDemo: 'Naive UI Demo',
DemosPrimevueDemo: 'PrimeVue Demo', DemosPrimevueDemo: 'PrimeVue Demo',
DemosWebsocketDemo: 'WebSocket Demo', DemosWebsocketDemo: 'WebSocket Demo',
Home: 'Home', Home: 'Home',
Login: 'Login', Login: 'Login',
Root: 'Index',
} satisfies PageTitleLocalizations; } satisfies PageTitleLocalizations;

View File

@@ -1,7 +1,7 @@
import type { I18nOptions } from 'vue-i18n'; import type { I18nOptions } from 'vue-i18n';
const modules = import.meta.glob(['./*.ts', '!./route-messages-auto-imports'], { const modules = import.meta.glob(['./*.ts', '!./route-messages-auto-imports'], {
eager: true, eager: true /* true 为同步false 为异步 */,
import: 'default', import: 'default',
}); });

View File

@@ -1,13 +1,25 @@
/*eslint perfectionist/sort-objects: "error"*/
/**
* 启用 perfectionist/sort-objects 规则以强制对象键按字母顺序排序
* 原因:
* 1. 减少多人协作时的合并冲突
* 2. 保持代码一致性,提高可维护性
*
* 运行以下命令自动修复排序:
* pnpm exec eslint --fix --no-ignore src/locales-utils/route-messages/
*/
export default { export default {
Root: '根 (Gēn)',
$Path: '$Path', $Path: '$Path',
Demos: '示例演示', Demos: '示例演示',
DemosApiDemo: 'API 调用示例', DemosApiDemo: 'API 调用示例',
DemosCounterDemo: '点击计数器', DemosCounterDemo: '点击计数器',
DemosCreate: '创建示例',
DemosI18nDemo: '国际化示例', DemosI18nDemo: '国际化示例',
DemosNaiveUiDemo: 'Naive UI 组件示例', DemosNaiveUiDemo: 'Naive UI 组件示例',
DemosPrimevueDemo: 'PrimeVue 组件示例', DemosPrimevueDemo: 'PrimeVue 组件示例',
DemosWebsocketDemo: 'WebSocket 示例', DemosWebsocketDemo: 'WebSocket 示例',
Home: '首页', Home: '首页',
Login: '登录', Login: '登录',
Root: '根 (Gēn)',
} satisfies PageTitleLocalizations; } satisfies PageTitleLocalizations;

View File

@@ -1,10 +1,10 @@
{ {
"page": { "page": {
"i18n-demo": { "i18n-demo": {
"title": "Vue I18n Demo",
"current-language": "Current Language",
"change-language": "Change Language", "change-language": "Change Language",
"hello": "Hello, {name}!" "current-language": "Current Language",
"hello": "Hello, {name}!",
"title": "Vue I18n Demo"
} }
} }
} }

View File

@@ -1,10 +1,10 @@
{ {
"page": { "page": {
"i18n-demo": { "i18n-demo": {
"title": "Vue I18n 示例",
"current-language": "当前语言",
"change-language": "切换语言", "change-language": "切换语言",
"hello": "你好, {name}" "current-language": "当前语言",
"hello": "你好, {name}",
"title": "Vue I18n 示例"
} }
} }
} }

View File

@@ -1,14 +1,14 @@
import './styles/index.ts'; import './styles/index.ts';
import { LogLevels } from 'consola'; import { LogLevels } from 'consola';
import App from './App.vue'; import App from './App.vue';
import { setupPlugins } from './plugins'; import { setupPlugins } from './plugins';
consola.level = LogLevels.verbose; consola.level = LogLevels.verbose;
const autoInstallModules = import.meta.glob('./plugins/!(index).ts', { const app = createApp(App);
eager: true /* true 为同步false 为异步 */, if (__DEV__) Object.defineProperty(window, '__APP__', { value: app });
}); setupPlugins(app);
const app = setupPlugins(createApp(App), autoInstallModules);
await new Promise((resolve) => setTimeout(resolve, 280)); await new Promise((resolve) => setTimeout(resolve, 280));
app.mount('#app'); app.mount('#app');

View File

@@ -1,5 +1,87 @@
<script setup lang="ts"></script> <script setup lang="ts">
definePage({ meta: { ignoreAuth: true, layout: false } });
const router = useRouter();
const userStore = useAuthStore();
const message = useMessage();
const formValue = ref({
username: 'admin',
password: 'admin',
});
const loading = ref(false);
async function handleLogin() {
if (!formValue.value.username || !formValue.value.password) {
message.warning('请输入用户名和密码');
return;
}
loading.value = true;
try {
const result = await userStore.login(formValue.value.username, formValue.value.password);
if (result.success) {
message.success('登录成功');
router.push('/');
} else {
message.error(result.message || '登录失败');
}
} catch {
message.error('登录异常');
} finally {
loading.value = false;
}
}
</script>
<template> <template>
<div>Login</div> <div class="login-page">
<NCard class="login-card" title="用户登录">
<NForm :model="formValue" label-placement="left" label-width="80">
<NFormItem label="用户名" path="username">
<NInput
v-model:value="formValue.username"
placeholder="请输入用户名"
@keyup.enter="handleLogin"
/>
</NFormItem>
<NFormItem label="密码" path="password">
<NInput
v-model:value="formValue.password"
type="password"
show-password-on="click"
placeholder="请输入密码"
@keyup.enter="handleLogin"
/>
</NFormItem>
<NFormItem :show-label="false">
<NButton type="primary" block :loading="loading" @click="handleLogin"> 登录 </NButton>
</NFormItem>
</NForm>
<div class="login-hint">
<NText depth="3">提示用户名和密码均为 admin</NText>
</div>
</NCard>
</div>
</template> </template>
<style scoped lang="scss">
.login-page {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.login-card {
width: 400px;
max-width: 90%;
}
.login-hint {
margin-top: 16px;
text-align: center;
}
</style>

View File

@@ -1,11 +1,29 @@
<script lang="ts" setup> <script lang="ts" setup>
defineProps<{ path: string }>(); defineProps<{ path: string }>();
declare global {
interface Window {
stack?: ReturnType<typeof createStackGuard>;
}
}
const stack = window?.stack;
const canGoBack = stack && stack.length > 1;
const router = useRouter();
function handleBack() {
if (canGoBack) {
router.back();
} else {
router.push('/');
}
}
</script> </script>
<template> <template>
<main flex-1 class="flex flex-col items-center justify-center h-full space-y-4"> <main flex-1 class="flex flex-col items-center justify-center h-full space-y-4">
<h1>Not Found</h1> <h1>Not Found</h1>
<p>{{ path }} does not exist.</p> <p>{{ path }} does not exist.</p>
<Button @click="$router.back()">Back</Button> <Button @click="handleBack">{{ canGoBack ? 'Back' : 'Home' }}</Button>
</main> </main>
</template> </template>

View File

@@ -128,7 +128,7 @@ const resetCount = () => {
</button> </button>
<!-- Naive UI 按钮 --> <!-- Naive UI 按钮 -->
<n-button <NButton
type="warning" type="warning"
size="large" size="large"
block block
@@ -148,7 +148,7 @@ const resetCount = () => {
</svg> </svg>
</template> </template>
点击 +1 (Naive UI) 点击 +1 (Naive UI)
</n-button> </NButton>
<!-- 重置按钮 --> <!-- 重置按钮 -->
<button <button

View File

@@ -0,0 +1,12 @@
<script setup lang="ts">
definePage({
meta: {
hideInMenu: true,
activeMenuName: 'Demos',
},
});
</script>
<template>
<div></div>
</template>

View File

@@ -9,22 +9,29 @@ function setLocale(newLocale: 'en-US' | 'zh-CN') {
<template> <template>
<div class="p-4"> <div class="p-4">
<n-h1>{{ t('page.i18n-demo.title') }}</n-h1> <NH1>{{ t('page.i18n-demo.title') }}</NH1>
<n-card :title="t('page.i18n-demo.change-language')"> <NCard :title="t('page.i18n-demo.change-language')">
<n-p> <NP>
{{ t('page.i18n-demo.current-language') }}: {{ t('page.i18n-demo.current-language') }}:
<span class="font-bold">{{ locale }}</span> <span class="font-bold">{{ locale }}</span>
</n-p> </NP>
<n-p> <NP>
{{ t('page.i18n-demo.hello', { name: 'Kilo' }) }} {{ t('page.i18n-demo.hello', { name: 'Kilo' }) }}
</n-p> </NP>
<n-space> <NSpace>
<n-button type="primary" @click="setLocale('en-US')"> English </n-button> <NButton type="primary" @click="setLocale('en-US')"> English </NButton>
<n-button type="success" @click="setLocale('zh-CN')"> 简体中文 </n-button> <NButton type="success" @click="setLocale('zh-CN')"> 简体中文 </NButton>
</n-space> </NSpace>
</n-card> </NCard>
<!-- 这里响应式有问题: -->
<NP> $route.meta.title: {{ $route.meta.title }} </NP>
<!-- 这样才正常 -->
<NP>
routeI18nInstance.global.t($route.name): {{ routeI18nInstance.global.t($route.name) }}
</NP>
</div> </div>
</template> </template>

View File

@@ -24,6 +24,7 @@ const FComponent: FunctionalComponent<{ prop: string }> = (props /* context */)
</> </>
); );
</script> </script>
<template> <template>
<NCard title="函数式组件TSX示例"> <NCard title="函数式组件TSX示例">
<FComponent prop="some-prop-value" /> <FComponent prop="some-prop-value" />

View File

@@ -1,12 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { useDialog, useMessage, useModal } from 'naive-ui';
import type { MessageType } from 'naive-ui'; import type { MessageType } from 'naive-ui';
import { useDialog, useMessage } from 'naive-ui';
definePage({ meta: {} }); definePage({ meta: {} });
const message = useMessage(); const message = useMessage();
const dialog = useDialog(); const dialog = useDialog();
const modal = useModal();
const messageTypes = ['info', 'success', 'warning', 'error', 'loading'] satisfies MessageType[]; const messageTypes = ['info', 'success', 'warning', 'error', 'loading'] satisfies MessageType[];
const dialogTypes = ['info', 'success', 'warning', 'error'] as const; const dialogTypes = ['info', 'success', 'warning', 'error'] as const;
@@ -38,11 +37,10 @@ const openDialog = (type: (typeof dialogTypes)[number]) => {
}; };
const openModal = () => { const openModal = () => {
modal.create({ window.$nModal!.create({
title: '命令式 Modal 示例', title: '命令式 Modal 示例',
content: '这是一个命令式 API 创建的 Modal 示例,使用 preset="dialog"。', content: '这是一个命令式 API 创建的 Modal 示例,使用 preset="dialog"。',
preset: 'dialog', preset: 'dialog',
maskClosable: false,
onPositiveClick: () => { onPositiveClick: () => {
message.success('点击了确定'); message.success('点击了确定');
}, },
@@ -62,7 +60,6 @@ const openModal = () => {
<NAlert title="信息" type="info" :bordered="false"> <NAlert title="信息" type="info" :bordered="false">
演示 Naive UI 各种组件的使用方法和功能特性 演示 Naive UI 各种组件的使用方法和功能特性
</NAlert> </NAlert>
<NCard title="Message 消息" class="mt-4"> <NCard title="Message 消息" class="mt-4">
<NSpace> <NSpace>
<NButton <NButton

View File

@@ -2,6 +2,6 @@
<template> <template>
<div> <div>
<h1>Index Page</h1> <NButton @click="$router.push({ name: 'DemosCreate' })">DemosCreate</NButton>
</div> </div>
</template> </template>

View File

@@ -1,5 +1,6 @@
export function install({ app }: { app: import('vue').App<Element> }) { export function install({ app }: { app: import('vue').App<Element> }) {
app.config.globalProperties.__DEV__ = __DEV__; app.config.globalProperties.__DEV__ =
__DEV__; /* vite.config.ts: define: { __DEV__: JSON.stringify(!isBuild) } */
app.config.errorHandler = (error, instance, info) => { app.config.errorHandler = (error, instance, info) => {
console.error('Global error:', error); console.error('Global error:', error);
@@ -10,17 +11,4 @@ export function install({ app }: { app: import('vue').App<Element> }) {
// 2. 显示全局错误提示 // 2. 显示全局错误提示
// 3. 进行错误分析和处理 // 3. 进行错误分析和处理
}; };
// if (import.meta.env.MODE === 'development' && '1' === ('2' as never)) {
// // TODO: https://github.com/hu3dao/vite-plugin-debug/
// // https://eruda.liriliri.io/zh/docs/#快速上手
// import('eruda').then(({ default: eruda }) => {
// eruda.init({
// defaults: {
// transparency: 0.9,
// },
// })
// /* eruda.show(); */
// })
// }
} }

View File

@@ -2,8 +2,8 @@ import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders';
import { setupLayouts } from 'virtual:meta-layouts'; import { setupLayouts } from 'virtual:meta-layouts';
// import { createGetRoutes, setupLayouts } from 'virtual:generated-layouts'; // import { createGetRoutes, setupLayouts } from 'virtual:generated-layouts';
import { createRouter, createWebHistory } from 'vue-router'; import { createRouter, createWebHistory } from 'vue-router';
import type { RouteNamedMap } from 'vue-router/auto-routes'; import type { Router } from 'vue-router';
import { routes, handleHotUpdate } from 'vue-router/auto-routes'; import { handleHotUpdate, routes } from 'vue-router/auto-routes';
const setupLayoutsResult = setupLayouts(routes); const setupLayoutsResult = setupLayouts(routes);
const router = createRouter({ const router = createRouter({
@@ -15,6 +15,10 @@ const router = createRouter({
strict: true, strict: true,
}); });
router.isReady().then(() => {
console.debug('✅ [router is ready]');
});
router.onError((error) => { router.onError((error) => {
console.debug('🚨 [router error]:', error); console.debug('🚨 [router error]:', error);
}); });
@@ -33,50 +37,24 @@ export function install({ app }: { app: import('vue').App<Element> }) {
// 警告:路由守卫的创建顺序会影响执行流程,请勿调整 // 警告:路由守卫的创建顺序会影响执行流程,请勿调整
createNProgressGuard(router); createNProgressGuard(router);
if (import.meta.env.VITE_APP_ENABLE_ROUTER_LOG_GUARD === 'true') createLogGuard(router); if (import.meta.env.VITE_APP_ENABLE_ROUTER_LOG_GUARD === 'true') createLogGuard(router);
Object.assign(globalThis, { stack: createStackGuard(router) }); Object.assign(window, { stack: createStackGuard(router) });
// >>>
Object.values(
import.meta.glob<{
createGuard?: (router: Router) => void;
}>('./router-guard/*.ts', { eager: true /* true 为同步false 为异步 */ }),
).forEach((module) => {
module.createGuard?.(router);
});
// <<<
} }
declare module 'vue-router' { if (__DEV__) Object.assign(window, { router });
/* definePage({ meta: { title: '示例演示' } }); */
interface RouteMeta {
/**
* @description 是否在菜单中隐藏
*/
hideInMenu?: boolean;
/**
* @description 菜单标题
* @deprecated //!⚠️请通过多语言标题方案(搜`PageTitleLocalizations`)维护标题
*/
title?: string;
/**
* @description 使用的布局,设置为 false 则表示不使用布局
*/
layout?: string | false;
/**
* @description 菜单项是否渲染为可点击链接,默认为 true
* - true: 使用 RouterLink 包装,可点击跳转
* - false: 仅渲染纯文本标签,不可点击(适用于分组标题)
*/
link?: boolean;
/**
* @description 菜单排序权重,数值越小越靠前,未设置则按路径字母顺序排序
*/
order?: number;
}
}
export { router, setupLayoutsResult };
declare global {
type PageTitleLocalizations = Record<keyof RouteNamedMap, string>;
}
if (__DEV__) Object.assign(globalThis, { router });
// This will update routes at runtime without reloading the page // This will update routes at runtime without reloading the page
if (import.meta.hot) { if (import.meta.hot) {
handleHotUpdate(router); handleHotUpdate(router);
} }
export { router, setupLayoutsResult };

View File

@@ -0,0 +1,50 @@
import type { RouteNamedMap } from 'vue-router/auto-routes';
declare global {
type PageTitleLocalizations = Record<keyof RouteNamedMap, string>;
}
declare module 'vue-router' {
/* definePage({ meta: { title: '示例演示' } }); */
interface RouteMeta {
/**
* @description 是否在菜单中隐藏
*/
hideInMenu?: boolean;
/**
* @description 菜单标题 // !⚠️通过多语言标题方案(搜`PageTitleLocalizations`)维护标题
*/
title?: string;
/**
* @description 使用的布局,设置为 false 则表示不使用布局
*/
layout?: string | false;
/**
* @description 菜单项是否渲染为可点击链接,默认为 true
* - true: 使用 RouterLink 包装,可点击跳转
* - false: 仅渲染纯文本标签,不可点击(适用于分组标题)
*/
link?: boolean;
/**
* @description 菜单排序权重,数值越小越靠前,未设置则按路径字母顺序排序
*/
order?: number;
/**
* @description 是否忽略权限,默认为 false
*/
ignoreAuth?: boolean;
/**
* @description 当前路由激活时应该高亮的菜单项(通过路由名称指定)
* - 用于隐藏在菜单中的子页面,指定其父级菜单项应该高亮
* - 使用路由名称而非路径,提供更好的类型安全和重构友好性
* - 例如:`activeMenuName: 'Demos'` 会高亮 Demos 菜单项
*/
activeMenuName?: keyof RouteNamedMap;
}
}

View File

@@ -5,12 +5,21 @@
import Aura from '@primeuix/themes/aura'; import Aura from '@primeuix/themes/aura';
import zhCN from 'primelocale/zh-CN.json'; import zhCN from 'primelocale/zh-CN.json';
import PrimeVue from 'primevue/config'; import PrimeVue from 'primevue/config';
import type { PrimeVueConfiguration } from 'primevue/config';
import StyleClass from 'primevue/styleclass'; import StyleClass from 'primevue/styleclass';
import ToastService from 'primevue/toastservice'; import ToastService from 'primevue/toastservice';
export function install({ app }: { app: import('vue').App<Element> }) { export function install({ app }: { app: import('vue').App<Element> }) {
app.directive('styleclass', StyleClass); app.directive('styleclass', StyleClass);
// https://github.com/primefaces/primevue/blob/afe6f58ae55e9caf7f9bc094cd453a21a6113001/packages/core/src/config/PrimeVue.js
app.use(PrimeVue, { app.use(PrimeVue, {
zIndex: {
modal: 5100,
overlay: 5000,
menu: 5000,
tooltip: 5100,
},
locale: { locale: {
...zhCN['zh-CN'], ...zhCN['zh-CN'],
completed: '已上传', completed: '已上传',
@@ -25,6 +34,6 @@ export function install({ app }: { app: import('vue').App<Element> }) {
}, },
preset: Aura, preset: Aura,
}, },
}); } satisfies PrimeVueConfiguration);
app.use(ToastService); app.use(ToastService);
} }

View File

@@ -4,13 +4,18 @@
type UserPlugin = (ctx: UserPluginContext) => void; type UserPlugin = (ctx: UserPluginContext) => void;
type AutoInstallModule = { [K: string]: unknown; install?: UserPlugin }; type AutoInstallModule = { [K: string]: unknown; install?: UserPlugin };
type UserPluginContext = { app: import('vue').App<Element> }; type UserPluginContext = { app: import('vue').App<Element> };
export function setupPlugins(
app: import('vue').App, const autoInstallModules: AutoInstallModule = import.meta.glob(
modules: AutoInstallModule | Record<string, unknown>, ['./*.ts', '!./**/*.types.ts', '!./index.ts'],
) { {
console.group('🔌 Plugins'); eager: true /* true 为同步false 为异步 */,
for (const path in modules) { },
const module = modules[path] as AutoInstallModule; );
export function setupPlugins(app: import('vue').App) {
console.group(`🔌 Installing ${Object.keys(autoInstallModules).length} plugins`);
for (const path in autoInstallModules) {
const module = autoInstallModules[path] as AutoInstallModule;
if (module.install) { if (module.install) {
module.install({ app }); module.install({ app });
console.debug(`%c✔ ${path}`, 'color: #07a'); console.debug(`%c✔ ${path}`, 'color: #07a');

View File

@@ -0,0 +1,28 @@
import type { Router } from 'vue-router';
export function createGuard(router: Router) {
router.beforeEach(async (to /* , from */) => {
const userStore = useAuthStore();
if (to.name === 'Login') {
userStore.clearToken('User navigated to login page');
}
if (to.meta.ignoreAuth) {
return true;
}
if (!userStore.isLoggedIn) {
console.debug('🔑 [permission-guard] 用户未登录,重定向到登录页');
return { name: 'Login' };
}
});
router.beforeResolve(async (/* to, from */) => {
const userStore = useAuthStore();
if (userStore.isLoggedIn && !userStore.userInfo) {
console.debug('🔑 [permission-guard] 用户信息不存在,尝试获取用户信息');
await userStore.fetchUserInfo();
}
});
}

View File

@@ -1,12 +1,16 @@
import type { BasicColorSchema } from '@vueuse/core';
import { useLocalStorage, useMediaQuery } from '@vueuse/core'; import { useLocalStorage, useMediaQuery } from '@vueuse/core';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { computed } from 'vue'; import { computed } from 'vue';
// >>>>> // >>>>>
// https://vueuse.org/core/useColorMode/#advanced-usage // https://vueuse.org/core/useColorMode/#advanced-usage
const { system, store: themeMode } = useColorMode({ const { system, store: themeMode } = useColorMode<BasicColorSchema>({
selector: 'html',
attribute: 'class',
modes: { light: '', dark: 'app-dark', auto: '' }, modes: { light: '', dark: 'app-dark', auto: '' },
disableTransition: false, disableTransition: false,
initialValue: 'auto',
}); });
const { state, next: cycleTheme } = useCycleList(['light', 'dark', 'auto'] as const, { const { state, next: cycleTheme } = useCycleList(['light', 'dark', 'auto'] as const, {
initialValue: themeMode, initialValue: themeMode,

View File

@@ -0,0 +1,45 @@
export const useAuthStore = defineStore('auth', () => {
const token = useLocalStorage<string | null>('auth-token', null);
const userInfo = ref<Record<string, any> | null>(null);
const isLoggedIn = computed(() => !!token.value);
function clearToken(reason?: string) {
consola.info('🚮 [auth-store] clear: ', reason);
token.value = null;
userInfo.value = null;
}
async function login(username: string, password: string) {
// 模拟登录延迟
await new Promise((resolve) => setTimeout(resolve, 500));
// 模拟验证
if (username === 'admin' && password === 'admin') {
token.value = `mock-token-${Date.now()}`;
await fetchUserInfo();
return { success: true };
}
return { success: false, message: '用户名或密码错误' };
}
async function fetchUserInfo() {
if (!token.value) {
return;
}
// 模拟获取用户信息延迟
await new Promise((resolve) => setTimeout(resolve, 300));
// 模拟从服务器获取用户信息
userInfo.value = {
id: 1,
username: 'admin',
nickname: '管理员',
roles: ['admin'],
};
}
return { token, isLoggedIn, userInfo, clearToken, login, fetchUserInfo };
});

View File

@@ -0,0 +1,9 @@
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.25s ease-in-out;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}

View File

@@ -1,6 +1,8 @@
import 'nprogress/nprogress.css'; // <link rel="stylesheet" href="https://testingcf.jsdelivr.net/npm/nprogress/nprogress.css" /> import 'nprogress/nprogress.css'; // <link rel="stylesheet" href="https://testingcf.jsdelivr.net/npm/nprogress/nprogress.css" />
import 'primeicons/primeicons.css'; import 'primeicons/primeicons.css';
import './reset-primevue.css';
import './css/reset-primevue.css';
import './css/transition.css';
import 'virtual:uno.css'; import 'virtual:uno.css';

View File

@@ -1,90 +0,0 @@
<script setup lang="ts">
import { get, set } from 'lodash-es';
const { formValue, SafeNForm, SafeNFormItem, formRef } = useSafeNForm({
initialFormValue: {
/* ⚠️:
如果没使用`SafeNFormItem`
这里`user`对象没有手动初始化的话,将会报错:
`can't access property "name", $setup.formValue.user is undefined`
*/
user: {
name: '',
age: 0,
},
phone: '',
},
});
function handleSetUserName() {
set(formValue.value, 'user.name', 'Alice');
}
function handleValidateClick() {
formRef.value?.validate((errors) => {
if (!errors) {
window.$nMessage!.success('Valid');
} else {
console.log(errors);
window.$nMessage!.error('Invalid');
}
});
}
</script>
<template>
<div p-4>
<div border>
<div>
<pre>formValue: {{ JSON.stringify(formValue, null, 2) }}</pre>
</div>
<div>get(formValue, 'user.name'): {{ get(formValue, 'user.name') }}</div>
</div>
<n-space mt-4>
<n-button @click="handleSetUserName">Set user.name</n-button>
</n-space>
<n-space item-class="flex-1">
<n-card title="SafeForm" mt-4>
<SafeNForm label-placement="left" label-width="auto">
<n-form-item
label="姓名"
path="user.name"
:rule="{ required: true, message: '请输入姓名', trigger: ['input'] }"
>
<n-input v-model:value="formValue.user.name" placeholder="输入姓名" />
</n-form-item>
<SafeNFormItem
#default="{ value, setValue }"
:rule="{ required: true, message: '请输入姓名', trigger: ['input'] }"
label="姓名"
path="user.name"
>
<NInput :value="value" placeholder="SafeNFormItem" @update:value="setValue" />
</SafeNFormItem>
<n-form-item
label="电话号码"
path="phone"
:rule="{ required: true, message: '请输入电话号码', trigger: ['blur'] }"
>
<n-input v-model:value="formValue.phone" placeholder="电话号码" />
</n-form-item>
<SafeNFormItem
label="电话号码"
path="phone"
:rule="{ required: true, message: '请输入电话号码', trigger: ['blur'] }"
>
<!-- 如果没有提供插槽会默认渲染一个`<NInput>` -->
</SafeNFormItem>
<n-form-item>
<n-button attr-type="button" @click="handleValidateClick"> 验证 </n-button>
</n-form-item>
</SafeNForm>
</n-card>
</n-space>
</div>
</template>

View File

@@ -1,121 +0,0 @@
/**
* https://www.naiveui.com/zh-CN/os-theme/components/form
*
* FIXME: `NForm` 和 `NFormItem` 的 slots 还没有实现。`NFormItemGi`组件。
*/
import { get, set } from 'lodash-es';
import type { FormInst, FormItemProps, FormProps } from 'naive-ui';
import { NForm, NFormItem, formItemProps, NInput, formProps } from 'naive-ui';
import type { Get, Paths } from 'type-fest';
import type { SlotsType } from 'vue';
import { Comment } from 'vue';
type UseSafeNFormOptions<FormValue> = {
initialFormValue?: FormValue;
};
export function useSafeNForm<T extends Record<string, any> = Record<string, unknown>>(
options: UseSafeNFormOptions<T> = {},
) {
const formRef = ref<FormInst | null>(null);
const formValue = ref<T>(structuredClone(toRaw(options.initialFormValue)) || ({} as T));
// 创建类型安全的 Form 组件
type SafeNFormProps = FormProps;
type SafeNFormSlots = SlotsType<{
default?: { count?: number };
}>;
const SafeNForm = defineComponent<SafeNFormProps, /* Emits */ [], /* EE */ never, SafeNFormSlots>(
(props, ctx) => {
return () => (
<NForm
{...props}
model={formValue.value}
ref={(inst) => {
formRef.value = inst as unknown as FormInst;
}}
>
{ctx.slots.default?.({})}
</NForm>
);
},
{
name: 'SafeNForm',
inheritAttrs: false,
props: formProps,
},
);
// <<<<<
// >>>>> 创建类型安全的 FormItem 组件
type SafeNFormItemProps<P extends Paths<T> & string> = FormItemProps & {
path: P;
};
type SafeNFormItemDefaultSlot<P extends Paths<T> & string> = {
value: Get<T, P>;
setValue: (val: Get<T, P>) => void;
};
const SafeNFormItemImpl = defineComponent<
SafeNFormItemProps<Paths<T> & string>,
/* Emits */ [],
/* EE */ never,
SlotsType<{ default: SafeNFormItemDefaultSlot<Paths<T> & string> }>
>(
(props, ctx) => {
return () => {
const value = get(formValue.value, props.path);
function setValue(val: typeof value) {
set(formValue.value, props.path, val);
}
const defaultSlotContent = ctx.slots.default?.({
value,
setValue,
});
// 如果没有提供默认 slot 内容,则渲染一个 NInput 作为默认输入组件
const renderDefaultNInput = defaultSlotContent?.some((v) => v.type !== Comment) ? null : (
<NInput value={value} onUpdate:value={setValue} />
);
return (
<NFormItem {...props} path={props.path}>
{defaultSlotContent}
{renderDefaultNInput}
</NFormItem>
);
};
},
{
name: 'SafeNFormItem',
inheritAttrs: false,
props: Object.keys(formItemProps) as unknown as [keyof FormItemProps],
},
);
// Expose a generic constructor so template literals narrow `path`.
type SafeNFormItemComponent = {
new <P extends Paths<T> & string>(
props: SafeNFormItemProps<P>,
): {
$props: SafeNFormItemProps<P>;
$slots: {
default?: (scope: SafeNFormItemDefaultSlot<P>) => VNode[];
};
};
};
const SafeNFormItem = SafeNFormItemImpl as SafeNFormItemComponent;
// <<<<<
return {
formValue,
SafeNForm,
SafeNFormItem,
formRef,
};
}

View File

@@ -14,7 +14,15 @@
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"],
"~/*": ["./src/*"]
} }
},
"vueCompilerOptions": {
"plugins": [
"vue-macros/volar",
"unplugin-vue-router/volar/sfc-route-blocks",
"unplugin-vue-router/volar/sfc-typed-router"
]
} }
} }

View File

@@ -1,5 +1,5 @@
{ {
"extends": "@tsconfig/node22/tsconfig.json", "extends": "@tsconfig/node24/tsconfig.json",
"include": [ "include": [
"vite.config.*", "vite.config.*",
"vitest.config.*", "vitest.config.*",

17
typed-router.d.ts vendored
View File

@@ -2,7 +2,7 @@
/* prettier-ignore */ /* prettier-ignore */
// @ts-nocheck // @ts-nocheck
// noinspection ES6UnusedImports // noinspection ES6UnusedImports
// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️ // Generated by unplugin-vue-router. !! DO NOT MODIFY THIS FILE !!
// It's recommended to commit this file. // It's recommended to commit this file.
// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry. // Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
@@ -58,6 +58,13 @@ declare module 'vue-router/auto-routes' {
Record<never, never>, Record<never, never>,
| never | never
>, >,
'DemosCreate': RouteRecordInfo<
'DemosCreate',
'/demos/create',
Record<never, never>,
Record<never, never>,
| never
>,
'DemosI18nDemo': RouteRecordInfo< 'DemosI18nDemo': RouteRecordInfo<
'DemosI18nDemo', 'DemosI18nDemo',
'/demos/i18n-demo', '/demos/i18n-demo',
@@ -143,13 +150,19 @@ declare module 'vue-router/auto-routes' {
views: views:
| never | never
} }
'src/pages/demos/create.page.vue': {
routes:
| 'DemosCreate'
views:
| never
}
'src/pages/demos/i18n-demo.page.vue': { 'src/pages/demos/i18n-demo.page.vue': {
routes: routes:
| 'DemosI18nDemo' | 'DemosI18nDemo'
views: views:
| never | never
} }
'src/pages/demos/naive-ui-demo.page.vue': { 'src/pages/demos/naive-ui-demo/index.page.vue': {
routes: routes:
| 'DemosNaiveUiDemo' | 'DemosNaiveUiDemo'
views: views:

View File

@@ -1,26 +1,33 @@
import vue from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx'; import vueJsx from '@vitejs/plugin-vue-jsx';
import { getPascalCaseRouteName } from 'unplugin-vue-router';
import vueRouter from 'unplugin-vue-router/vite'; import vueRouter from 'unplugin-vue-router/vite';
import type { PluginOption } from 'vite';
import VueMacros from 'vue-macros/vite'; import VueMacros from 'vue-macros/vite';
export default [ import type { LoadPluginFunction } from './_loadPlugins';
VueMacros({
plugins: {
vue: vue({ include: [/\.vue$/, /\.md$/] }),
vueJsx: vueJsx(),
// https://uvr.esm.is/guide/configuration.html export const loadPlugin: LoadPluginFunction = async (_pluginLoadOptions) => {
// https://github.com/posva/unplugin-vue-router return [
// ⚠️ Vue must be placed after VueRouter() VueMacros({
vueRouter: vueRouter({ plugins: {
exclude: ['**/__*', '**/__*/**/*'], vue: vue({ include: [/\.vue$/, /\.md$/] }),
extensions: ['.page.vue', '.page.md'], vueJsx: vueJsx(),
getRouteName: (routeNode) => getPascalCaseRouteName(routeNode),
logs: false, // https://uvr.esm.is/guide/configuration.html
routesFolder: 'src/pages', // https://github.com/posva/unplugin-vue-router
}), // ⚠️ Vue must be placed after VueRouter()
}, vueRouter: vueRouter({
}), routesFolder: 'src/pages',
] satisfies PluginOption; extensions: ['.page.vue', '.page.md'],
exclude: ['**/__*', '**/__*/**/*'],
getRouteName: (await import('unplugin-vue-router')).getPascalCaseRouteName,
beforeWriteFiles(rootRoute) {
for (/* 深度优先遍历 */ const route of rootRoute.traverseDFS()) {
route.addToMeta({ _: route.fullPath });
}
},
logs: !true,
}),
},
}),
];
};

View File

@@ -1,10 +1,13 @@
import type { PluginOption } from 'vite';
import UnoCSS from 'unocss/vite'; import UnoCSS from 'unocss/vite';
export default [ import type { LoadPluginFunction } from './_loadPlugins';
// https://github.com/antfu/unocss
// see uno.config.ts for config export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
UnoCSS({ return [
checkImport: true, // https://github.com/antfu/unocss
}), // see uno.config.ts for config
] satisfies PluginOption; UnoCSS({
checkImport: true,
}),
];
};

View File

@@ -1,18 +1,21 @@
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'; import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
import type { PluginOption } from 'vite';
export default [ import type { LoadPluginFunction } from './_loadPlugins';
// https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n
VueI18nPlugin({
/* options */
// locale messages resource pre-compile option
include: ['src/locales/**'],
// https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n#transformi18nblock export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
// transformI18nBlock(src) { return [
// console.debug(`src :>> `, src); // https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n
// console.debug(`typeof src :>> `, typeof src); VueI18nPlugin({
// return src as string; /* options */
// }, // locale messages resource pre-compile option
}), include: ['src/locales/**'],
] satisfies PluginOption;
// https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n#transformi18nblock
// transformI18nBlock(src) {
// console.debug(`src :>> `, src);
// console.debug(`typeof src :>> `, typeof src);
// return src as string;
// },
}),
];
};

View File

@@ -1,9 +1,12 @@
import type { PluginOption } from 'vite';
import Markdown from 'unplugin-vue-markdown/vite'; import Markdown from 'unplugin-vue-markdown/vite';
export default [ import type { LoadPluginFunction } from './_loadPlugins';
// https://github.com/unplugin/unplugin-vue-markdown
Markdown({ export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
headEnabled: true, return [
}), // https://github.com/unplugin/unplugin-vue-markdown
] satisfies PluginOption; Markdown({
headEnabled: true,
}),
];
};

View File

@@ -1,17 +1,20 @@
import type { PluginOption } from 'vite';
import MetaLayouts from 'vite-plugin-vue-meta-layouts'; import MetaLayouts from 'vite-plugin-vue-meta-layouts';
export default [ import type { LoadPluginFunction } from './_loadPlugins';
// https://github.com/dishait/vite-plugin-vue-meta-layouts
MetaLayouts({ export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
target: 'src/layouts', return [
excludes: ['**/!(the-)*.vue'], // 排除非 the- 开头的文件。 // https://github.com/dishait/vite-plugin-vue-meta-layouts
metaName: 'layout', MetaLayouts({
// defaultLayout: 'sakai-vue/AppLayout', target: 'src/layouts',
// defaultLayout: 'naive-ui/AppLayout', excludes: ['**/!(the-)*.vue'], // 排除非 the- 开头的文件。
defaultLayout: 'base-layout/the-base-layout', metaName: 'layout',
// !⬇️: 当设置为 `sync` 时,注意`import 'virtual:uno.css'`的顺序问题。 // defaultLayout: 'sakai-vue/AppLayout',
// importMode: 'sync', // 默认为自动处理SSG 时为 sync非 SSG 时为 async // defaultLayout: 'naive-ui/AppLayout',
skipTopLevelRouteLayout: true, // 打开修复 https://github.com/JohnCampionJr/vite-plugin-vue-layouts/issues/134默认为 false 关闭 defaultLayout: 'base-layout/the-base-layout',
}), // !⬇️: 当设置为 `sync` 时,注意`import 'virtual:uno.css'`的顺序问题。
] satisfies PluginOption; // importMode: 'sync', // 默认为自动处理SSG 时为 sync非 SSG 时为 async
skipTopLevelRouteLayout: true, // 打开修复 https://github.com/JohnCampionJr/vite-plugin-vue-layouts/issues/134默认为 false 关闭
}),
];
};

View File

@@ -9,7 +9,6 @@ import Icons from 'unplugin-icons/vite';
import Components from 'unplugin-vue-components/vite'; import Components from 'unplugin-vue-components/vite';
import { VueRouterAutoImports } from 'unplugin-vue-router'; import { VueRouterAutoImports } from 'unplugin-vue-router';
import { createUtils4uAutoImports } from 'utils4u/auto-imports'; import { createUtils4uAutoImports } from 'utils4u/auto-imports';
import type { ConfigEnv, PluginOption } from 'vite';
// >>>>> // >>>>>
// eslint-disable-next-line import/no-duplicates // eslint-disable-next-line import/no-duplicates
@@ -26,6 +25,8 @@ import { PrimeVueResolver } from '@primevue/auto-import-resolver';
import { VantResolver } from '@vant/auto-import-resolver'; import { VantResolver } from '@vant/auto-import-resolver';
// <<<<< // <<<<<
import type { LoadPluginFunction } from './_loadPlugins';
function _getNaiveUiComponentNames() { function _getNaiveUiComponentNames() {
// [dtsTsx](https://github.com/unplugin/unplugin-vue-components/pull/673/files/84e80738885cfe11298f41f070cda94a7a779276) // [dtsTsx](https://github.com/unplugin/unplugin-vue-components/pull/673/files/84e80738885cfe11298f41f070cda94a7a779276)
@@ -55,7 +56,7 @@ function _getNaiveUiComponentNames() {
return []; return [];
} }
export function loadPlugin(_configEnv: ConfigEnv): PluginOption { export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
return [ return [
// https://github.com/antfu/unplugin-auto-import // https://github.com/antfu/unplugin-auto-import
AutoImport({ AutoImport({
@@ -76,7 +77,7 @@ export function loadPlugin(_configEnv: ConfigEnv): PluginOption {
createUtils4uAutoImports(['primevue']), createUtils4uAutoImports(['primevue']),
{ {
'consola/browser': ['consola'], 'consola/browser': ['consola'],
'vue-router/auto': ['useLink'], 'unplugin-vue-router/data-loaders/basic': ['defineBasicLoader'],
'naive-ui': [ 'naive-ui': [
'useModal', 'useModal',
'useDialog', 'useDialog',
@@ -141,4 +142,4 @@ export function loadPlugin(_configEnv: ConfigEnv): PluginOption {
}, },
}), }),
]; ];
} };

View File

@@ -1,6 +1,7 @@
import { minify as minifyHtml } from 'html-minifier-terser'; import { minify as minifyHtml } from 'html-minifier-terser';
import { loadEnv } from 'vite'; import type { PluginOption } from 'vite';
import type { ConfigEnv, PluginOption } from 'vite';
import type { LoadPluginFunction } from './_loadPlugins';
function IndexHtmlPlugin(): PluginOption { function IndexHtmlPlugin(): PluginOption {
return { return {
@@ -26,7 +27,79 @@ function IndexHtmlPlugin(): PluginOption {
}; };
} }
export function loadPlugin(_configEnv: ConfigEnv): PluginOption { function ___(): PluginOption {
const env = loadEnv(_configEnv.mode, process.cwd()); // https://github.com/hu3dao/vite-plugin-debug/blob/2935025e8ce082b9a5aef04766bcae3e996b3e55/src/index.ts
if (env.VITE_BUILD_MINIFY === 'true') return IndexHtmlPlugin(); return {
name: 'vant-touch-emulator-online',
apply: 'build',
transformIndexHtml(html) {
return {
html,
tags: [
{
tag: 'script',
attrs: {
src: 'https://testingcf.jsdelivr.net/npm/@vant/touch-emulator/dist/index.min.js',
// 这里的 `.min.js` 是 jsDelivr 的特殊处理
// src: 'https://unpkg.luckincdn.com/@vant/touch-emulator@1.4.0/dist/index.js',
},
injectTo: 'body',
},
// >>>>> eruda
{
tag: 'script',
attrs: {
src: 'https://testingcf.jsdelivr.net/npm/eruda/eruda.js',
},
injectTo: 'body',
},
{
tag: 'script',
children: `eruda.init();`,
injectTo: 'body',
},
// https://eruda.liriliri.io/zh/docs/#快速上手
// import('eruda').then(({ default: eruda }) => {
// eruda.init({
// defaults: {
// transparency: 0.9,
// },
// })
// /* eruda.show(); */
// })
// }
// <<<<<
// >>>>> vConsole
{
tag: 'script',
attrs: {
src: 'https://cdn.jsdelivr.net/npm/vconsole@latest/dist/vconsole.min.js',
},
injectTo: 'body',
},
{
tag: 'script',
children: `new window.VConsole();`,
injectTo: 'body',
},
// <<<<<
],
};
},
};
} }
export const loadPlugin: LoadPluginFunction = (pluginLoadOptions) => {
const { mode, env } = pluginLoadOptions;
// return [___()];
if (mode !== 'production') {
return { plugins: [], message: '仅在生产模式下启用' };
}
if (env.VITE_BUILD_MINIFY !== 'true') {
return { plugins: [], message: `已通过环境变量禁用: VITE_BUILD_MINIFY=${env.VITE_BUILD_MINIFY}` };
}
return IndexHtmlPlugin();
};

View File

@@ -1,16 +1,16 @@
import { consola } from 'consola';
import type { ConfigEnv, PluginOption } from 'vite';
import { vitePluginFakeServer } from 'vite-plugin-fake-server'; import { vitePluginFakeServer } from 'vite-plugin-fake-server';
// https://github.com/condorheroblog/vite-plugin-fake-server?tab=readme-ov-file#usage
export function loadPlugin(_configEnv: ConfigEnv): PluginOption { import type { LoadPluginFunction } from './_loadPlugins';
if (_configEnv.mode !== 'development') {
consola.info('fake server plugin is disabled in non-development mode.'); // https://github.com/condorheroblog/vite-plugin-fake-server?tab=readme-ov-file#usage
return []; export const loadPlugin: LoadPluginFunction = (pluginLoadOptions) => {
const { mode } = pluginLoadOptions;
if (mode !== 'development') {
return { plugins: [], message: '仅在开发模式下启用' };
} }
return vitePluginFakeServer({ return vitePluginFakeServer({
basename: 'fake-api', basename: 'fake-api',
enableProd: true, enableProd: true,
include: 'fake', include: 'fake',
}); });
} };

View File

@@ -1,9 +1,12 @@
import type { PluginOption } from 'vite';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'; import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
export default [ import type { LoadPluginFunction } from './_loadPlugins';
// https://github.com/FatehAK/vite-plugin-image-optimizer?tab=readme-ov-file#default-configuration
ViteImageOptimizer({ export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
/* pass your config */ return [
}), // https://github.com/FatehAK/vite-plugin-image-optimizer?tab=readme-ov-file#default-configuration
] satisfies PluginOption; ViteImageOptimizer({
/* pass your config */
}),
];
};

View File

@@ -1,20 +1,27 @@
import consola from 'consola';
import type { ConfigEnv, PluginOption } from 'vite';
import { loadEnv } from 'vite';
import vueDevTools from 'vite-plugin-vue-devtools'; import vueDevTools from 'vite-plugin-vue-devtools';
export function loadPlugin(configEnv: ConfigEnv): PluginOption { import type { LoadPluginFunction } from './_loadPlugins';
const env = loadEnv(configEnv.mode, process.cwd());
if (configEnv.command === 'build') { export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
consola.info('vue-devtools plugin is not used in build mode.'); const { mode } = _pluginLoadOptions;
return []; if (mode !== 'development') {
return { plugins: [], message: '仅在开发模式下启用' };
} }
if (env.VITE_APP_ENABLE_VUE_DEVTOOLS !== 'true') { let launchEditor = 'code';
consola.info('vue-devtools plugin disabled by env'); let message: string | undefined;
return [];
if (process.env.TERM_PROGRAM_VERSION?.toLowerCase()?.includes('insider')) {
launchEditor = 'code-insiders';
message = '检测到 VSCode Insiders 环境';
} }
return [vueDevTools()]; return {
} plugins: [
vueDevTools({
launchEditor: launchEditor,
}),
],
message,
};
};

View File

@@ -1,16 +1,17 @@
import { cloudflare } from '@cloudflare/vite-plugin'; import { cloudflare } from '@cloudflare/vite-plugin';
import { loadEnv } from 'vite';
import type {ConfigEnv, PluginOption} from 'vite';
export function loadPlugin(_configEnv: ConfigEnv): PluginOption { import type { LoadPluginFunction } from './_loadPlugins';
const env = loadEnv(_configEnv.mode, process.cwd());
if (_configEnv.mode === 'test') { export const loadPlugin: LoadPluginFunction = (pluginLoadOptions) => {
console.log('cloudflare plugin disabled in test mode'); const { mode, env } = pluginLoadOptions;
return []; if (mode === 'test') {
return { plugins: [], message: '在测试模式下禁用' };
} }
if (env.VITE_CLOUDFLARE_SERVER_ENABLED !== 'true') { if (env.VITE_CLOUDFLARE_SERVER_ENABLED !== 'true') {
console.log('cloudflare plugin disabled by env'); return {
return []; plugins: [],
message: `已通过环境变量禁用: VITE_CLOUDFLARE_SERVER_ENABLED=${env.VITE_CLOUDFLARE_SERVER_ENABLED}`,
};
} }
return [cloudflare()]; return [cloudflare()];
} };

View File

@@ -1,28 +1,47 @@
import boxen from 'boxen';
import consola from 'consola';
import path from 'node:path'; import path from 'node:path';
import { pathToFileURL } from 'node:url'; import { pathToFileURL } from 'node:url';
import consola from 'consola';
import { glob } from 'tinyglobby'; import { glob } from 'tinyglobby';
import type { ConfigEnv, PluginOption } from 'vite'; import type { ConfigEnv, PluginOption } from 'vite';
import { loadEnv } from 'vite';
export type LoadPluginFunction = (
configEnv: ConfigEnv & {
env: Record<string, string>;
},
) => PluginOption | LoadPluginResult;
export interface LoadPluginResult {
plugins: PluginOption;
message?: string;
}
type LoadPluginFunction = (configEnv: ConfigEnv) => PluginOption;
export async function loadPlugins(configEnv: ConfigEnv): Promise<PluginOption[]> { export async function loadPlugins(configEnv: ConfigEnv): Promise<PluginOption[]> {
const plugins: PluginOption[] = []; const plugins: PluginOption[] = [];
consola.start('开始加载 Vite 插件...'); const cwd = path.resolve(import.meta.dirname);
const pluginEntries = await glob('**/*.ts', { const pluginEntries = await glob('**/*.ts', {
absolute: true, absolute: true,
cwd: path.resolve(import.meta.dirname), cwd,
ignore: [ ignore: [
'**/*.d.ts', '**/*.d.ts',
'**/*.disabled.ts', '**/*.disabled.ts',
'**/x-*.ts', // 禁用以 x- 开头的插件文件 '**/x-*.ts', // 禁用以 x- 开头的插件文件
'**/*-x.ts', // 禁用以 -x 结尾的插件文件
'**/*-X.ts', // 禁用以 -X 结尾的插件文件
'**/_*', '**/_*',
], ],
}); });
consola.info(`找到 ${pluginEntries.length} 个插件文件`); const relativeCwd = path.relative(process.cwd(), cwd);
console.time('加载插件');
consola.log(
boxen(`正在加载 Vite 插件... (./${relativeCwd})`, {
borderStyle: 'classic',
borderColor: 'cyan',
}),
);
// 计算最长的文件名长度,用于对齐输出 // 计算最长的文件名长度,用于对齐输出
const maxNameLength = Math.max(...pluginEntries.map((entry) => path.basename(entry).length)); const maxNameLength = Math.max(...pluginEntries.map((entry) => path.basename(entry).length));
@@ -33,36 +52,39 @@ export async function loadPlugins(configEnv: ConfigEnv): Promise<PluginOption[]>
const imported = await import(pathToFileURL(entry).href); const imported = await import(pathToFileURL(entry).href);
const loadPlugin = imported.loadPlugin as LoadPluginFunction | undefined; const loadPlugin = imported.loadPlugin as LoadPluginFunction | undefined;
let plugin: PluginOption | undefined;
let loadMethod = '';
// 优先使用 loadPlugin 函数(接收 configEnv 参数) if (!loadPlugin || typeof loadPlugin !== 'function') {
if (loadPlugin && typeof loadPlugin === 'function') { consola.warn(`插件未导出 loadPlugin 函数: ${paddedName}`);
plugin = loadPlugin(configEnv); continue;
loadMethod = 'loadPlugin';
} else if (imported.default) {
plugin = imported.default;
loadMethod = 'default';
} else {
consola.warn(`插件未导出有效内容: ${paddedName}`);
continue; // 跳过无效插件
} }
if (plugin) { const env = loadEnv(configEnv.mode, process.cwd());
const pluginArray = Array.isArray(plugin) ? plugin : [plugin]; const result = loadPlugin({ ...configEnv, env });
const validPlugins = pluginArray.filter(Boolean); // 过滤掉 null/undefined
const pluginCount = validPlugins.length;
if (pluginCount > 0) { // 判断是否是 LoadPluginResult 对象
plugins.push(...validPlugins); const isResultObject = (val: unknown): val is LoadPluginResult =>
consola.success(`${paddedName}${pluginCount} 个实例 (${loadMethod})`); typeof val === 'object' && val !== null && 'plugins' in val;
} else {
consola.info(`${paddedName} 返回了空数组或无效值`); const plugin = isResultObject(result) ? result.plugins : result;
} const message = isResultObject(result) ? result.message : undefined;
const pluginArray = Array.isArray(plugin) ? plugin : [plugin];
const validPlugins = pluginArray.filter(Boolean);
const pluginCount = validPlugins.length;
if (pluginCount > 0) {
plugins.push(...validPlugins);
const suffix = message ? ` (${message})` : '';
consola.info(`${paddedName}${pluginCount} 个实例${suffix}`);
} else if (message) {
consola.info(`${paddedName}${message}`);
} else {
consola.info(`${paddedName} 返回了空数组或无效值`);
} }
} }
consola.success(`✅ 总共加载了 ${plugins.length} 个插件实例`); consola.success(` ${pluginEntries.length} 个插件文件,已加载 ${plugins.length}实例`);
console.timeEnd('加载插件');
return plugins; return plugins;
} }

View File

@@ -1,13 +1,16 @@
import type { ConfigEnv, PluginOption } from 'vite'; import type { LoadPluginFunction } from './_loadPlugins';
import { loadEnv } from 'vite';
export default [ export const loadPlugin: LoadPluginFunction = (_pluginLoadOptions) => {
// ... const env = _pluginLoadOptions.env;
] satisfies PluginOption;
export function loadPlugin(_configEnv: ConfigEnv): PluginOption { // 示例:根据环境变量禁用插件并返回消息
const env = loadEnv(_configEnv.mode, process.cwd()); if (env.VITE_DEMO_ENABLED !== 'true') {
console.debug(`env :>> `, env); return {
// ... plugins: [],
return undefined; message: `已通过环境变量禁用: VITE_DEMO_ENABLED=${env.VITE_DEMO_ENABLED}`,
} };
}
// 正常返回插件
return [];
};

View File

@@ -1,17 +0,0 @@
import type { PluginOption } from 'vite';
export default [
// // 检查是否在VS Code终端中运行
// if (process.env.TERM_PROGRAM === 'vscode' || process.env.VSCODE_PID) {
// // plugins.push(
// // // 构建后自动将dist目录打包成zip文件
// // viteArchiverPlugin({
// // addTimestamp: false, // 是否添加时间戳到输出文件名
// // format: 'zip', // 输出的压缩文件格式
// // outputDir: '', // 输出目录,默认为项目根目录
// // outputFileName: 'dist', // 输出的zip文件名不含扩展名
// // sourceDir: 'dist', // 要打包的源目录
// // }),
// // )
// }
] satisfies PluginOption;

View File

@@ -1,6 +1,6 @@
import type { ManualChunkMeta, PreRenderedAsset, RollupOptions } from 'rollup'; import type { /* ManualChunkMeta, PreRenderedAsset, */ RollupOptions } from 'rollup';
import path from 'node:path'; // import path from 'node:path';
// https://www.npmjs.com/package/utils4u/v/2.19.2?activeTab=code // https://www.npmjs.com/package/utils4u/v/2.19.2?activeTab=code
@@ -12,106 +12,95 @@ export const viteConfigRollupOptions: RollupOptions = {
if (warning.code === 'EVAL' && warning.id?.includes('node_modules/protobufjs')) return; if (warning.code === 'EVAL' && warning.id?.includes('node_modules/protobufjs')) return;
warn(warning); warn(warning);
}, */ }, */
output: { output: {
// Keep hashed file names predictable across entry, chunk, and asset outputs. // 如果一个 chunk 小于 10KBRollup 会尝试将它合并到其他 chunk 中。这样可以避免产生大量碎片文件
entryFileNames: 'entry/[name].[hash].js', // 默认: "[name].js" experimentalMinChunkSize: 10 * 1024,
chunkFileNames: 'chunk/[name].[hash].js', // 默认: "[name]-[hash].js" // // Keep hashed file names predictable across entry, chunk, and asset outputs.
// assetFileNames:'', // 默认: "assets/[name]-[hash][extname]" // entryFileNames: 'entry/[name].[hash].js', // 默认: "[name].js"
// https://cn.rollupjs.org/configuration-options/#output-assetfilenames // chunkFileNames: 'chunk/[name].[hash].js', // 默认: "[name]-[hash].js"
assetFileNames(chunkInfo: PreRenderedAsset) { // // assetFileNames:'', // 默认: "assets/[name]-[hash][extname]"
const names = [...new Set(chunkInfo.names)]; // // https://cn.rollupjs.org/configuration-options/#output-assetfilenames
// assetFileNames(chunkInfo: PreRenderedAsset) {
if (names.length !== 1) { // const names = [...new Set(chunkInfo.names)];
console.error('Multiple names for asset:', chunkInfo); // if (names.length !== 1) {
process.exit(1); // console.error('Multiple names for asset:', chunkInfo);
} // process.exit(1);
// }
const assetName = names[0]; // const assetName = names[0];
const ext = assetName.split('.').pop()?.toLowerCase(); // const ext = assetName.split('.').pop()?.toLowerCase();
if (ext && /png|jpe?g|gif|svg|webp|avif/.test(ext)) { // if (ext && /png|jpe?g|gif|svg|webp|avif/.test(ext)) {
return 'chunks/images/[name].[hash][extname]'; // return 'chunks/images/[name].[hash][extname]';
} // }
if (ext && /woff2?|ttf|otf/.test(ext)) { // if (ext && /woff2?|ttf|otf/.test(ext)) {
return 'chunks/fonts/[name].[hash][extname]'; // return 'chunks/fonts/[name].[hash][extname]';
} // }
if (ext === 'css') { // if (ext === 'css') {
return 'chunks/css/[name].[hash][extname]'; // return 'chunks/css/[name].[hash][extname]';
} // }
return '_chunks/[name].[hash][extname]'; // return '_chunks/[name].[hash][extname]';
}, // },
// manualChunks: (id: string, _meta: ManualChunkMeta) => {
manualChunks: (id: string, _meta: ManualChunkMeta) => { // // https://github.com/unocss/unocss/issues/4917
// https://github.com/unocss/unocss/issues/4917 // // if (['/src/layouts'].some((prefix) => id.includes(prefix))) {
// if (['/src/layouts'].some((prefix) => id.includes(prefix))) { // // const url = new URL(id, 'file://');
// const url = new URL(id, 'file://'); // // if (!url.search /* ?vue&type=script&setup=true&lang.ts */) {
// if (!url.search /* ?vue&type=script&setup=true&lang.ts */) { // // return 'layouts';
// return 'layouts'; // // }
// } // // }
// } // if (id.includes('meta-layouts')) {
// // console.debug(`id :>> `, id); // id :>> virtual:meta-layouts
if (id.includes('meta-layouts')) { // // 这里很奇怪,打印 id 是`virtual:meta-layouts`,但是 `'virtual:meta-layouts' === id` 却是 false
// console.debug(`id :>> `, id); // id :>> virtual:meta-layouts // return 'lib-meta-layouts';
// 这里很奇怪,打印 id 是`virtual:meta-layouts`,但是 `'virtual:meta-layouts' === id` 却是 false // }
return 'lib-meta-layouts'; // if (id.includes('index.page.vue')) {
} // const url = new URL(id, 'file://');
// if (!url.search /* ?vue&type=script&setup=true&lang.ts */) {
if (id.includes('index.page.vue')) { // const parentDir = path.basename(path.dirname(id));
const url = new URL(id, 'file://'); // return `${parentDir}-index.page`;
if (!url.search /* ?vue&type=script&setup=true&lang.ts */) { // }
const parentDir = path.basename(path.dirname(id)); // }
return `${parentDir}-index.page`; // if (!id.includes('node_modules')) return;
} // // 处理 pnpm 的特殊路径结构
} // let packageName;
// if (id.includes('.pnpm')) {
if (!id.includes('node_modules')) return; // // pnpm 路径: .pnpm/naive-ui@2.43.1_vue@3.5.22/node_modules/naive-ui/...
// 处理 pnpm 的特殊路径结构 // const pnpmMatch = id.match(/\.pnpm\/(.+?)@/);
let packageName; // if (pnpmMatch) {
if (id.includes('.pnpm')) { // packageName = pnpmMatch[1];
// pnpm 路径: .pnpm/naive-ui@2.43.1_vue@3.5.22/node_modules/naive-ui/... // }
const pnpmMatch = id.match(/\.pnpm\/(.+?)@/); // } else {
if (pnpmMatch) { // // 普通路径: node_modules/lodash/...
packageName = pnpmMatch[1]; // const normalMatch = id.match(/node_modules\/(@[^/]+\/[^/]+|[^/]+)\//);
} // if (normalMatch) {
} else { // packageName = normalMatch[1];
// 普通路径: node_modules/lodash/... // }
const normalMatch = id.match(/node_modules\/(@[^/]+\/[^/]+|[^/]+)\//); // }
if (normalMatch) { // if (packageName) {
packageName = normalMatch[1]; // if (['highlight.js'].includes(packageName)) {
} // return 'lib-hljs';
} // }
// // 根据包名分组
if (packageName) { // if (['consola', 'lodash', '@juggle+resize-observer', 'vueuc'].includes(packageName)) {
if (['highlight.js'].includes(packageName)) { // return 'lib-vendor';
return 'lib-hljs'; // }
} // // // 拆了有问题
// // if (['naive-ui'].includes(packageName) && id.includes('_internal')) {
// 根据包名分组 // // return 'lib-naive-ui-internal';
if (['consola', 'lodash', '@juggle+resize-observer', 'vueuc'].includes(packageName)) { // // }
return 'lib-vendor'; // if (['naive-ui'].includes(packageName)) {
} // return 'lib-naive-ui';
// }
// // 拆了有问题 // if (
// if (['naive-ui'].includes(packageName) && id.includes('_internal')) { // ['primelocale', 'primevue', 'primeuix', 'primeicons'].some((name) =>
// return 'lib-naive-ui-internal'; // packageName!.includes(name),
// } // )
// ) {
if (['naive-ui'].includes(packageName)) { // return 'lib-primevue';
return 'lib-naive-ui'; // }
} // if (['vue', 'vue-router', 'pinia', 'vue-demi', 'vue-i18n'].includes(packageName)) {
// return 'lib-vue-vendor';
if ( // }
['primelocale', 'primevue', 'primeuix', 'primeicons'].some((name) => // }
packageName!.includes(name), // },
)
) {
return 'lib-primevue';
}
if (['vue', 'vue-router', 'pinia', 'vue-demi', 'vue-i18n'].includes(packageName)) {
return 'lib-vue-vendor';
}
}
},
}, },
}; };

View File

@@ -40,6 +40,7 @@ export default defineConfig(async (configEnv) => {
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)), '@': fileURLToPath(new URL('./src', import.meta.url)),
'~': fileURLToPath(new URL('./src', import.meta.url)),
}, },
}, },
define: { define: {

File diff suppressed because it is too large Load Diff