@moluoxixi/create-app 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +129 -0
  3. package/dist/commands/create.d.ts +10 -0
  4. package/dist/commands/create.d.ts.map +1 -0
  5. package/dist/commands/create.js +89 -0
  6. package/dist/commands/create.js.map +1 -0
  7. package/dist/commands/index.d.ts +5 -0
  8. package/dist/commands/index.d.ts.map +1 -0
  9. package/dist/commands/index.js +5 -0
  10. package/dist/commands/index.js.map +1 -0
  11. package/dist/generators/index.d.ts +7 -0
  12. package/dist/generators/index.d.ts.map +1 -0
  13. package/dist/generators/index.js +7 -0
  14. package/dist/generators/index.js.map +1 -0
  15. package/dist/generators/project.d.ts +11 -0
  16. package/dist/generators/project.d.ts.map +1 -0
  17. package/dist/generators/project.js +26 -0
  18. package/dist/generators/project.js.map +1 -0
  19. package/dist/generators/react.d.ts +10 -0
  20. package/dist/generators/react.d.ts.map +1 -0
  21. package/dist/generators/react.js +39 -0
  22. package/dist/generators/react.js.map +1 -0
  23. package/dist/generators/vue.d.ts +10 -0
  24. package/dist/generators/vue.d.ts.map +1 -0
  25. package/dist/generators/vue.js +40 -0
  26. package/dist/generators/vue.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +26 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/test.d.ts +6 -0
  32. package/dist/test.d.ts.map +1 -0
  33. package/dist/test.js +364 -0
  34. package/dist/test.js.map +1 -0
  35. package/dist/types/ejs.d.ts +11 -0
  36. package/dist/types/ejs.d.ts.map +1 -0
  37. package/dist/types/ejs.js +5 -0
  38. package/dist/types/ejs.js.map +1 -0
  39. package/dist/types/features.d.ts +26 -0
  40. package/dist/types/features.d.ts.map +1 -0
  41. package/dist/types/features.js +41 -0
  42. package/dist/types/features.js.map +1 -0
  43. package/dist/types/index.d.ts +59 -0
  44. package/dist/types/index.d.ts.map +1 -0
  45. package/dist/types/index.js +8 -0
  46. package/dist/types/index.js.map +1 -0
  47. package/dist/types/viteConfig.d.ts +17 -0
  48. package/dist/types/viteConfig.d.ts.map +1 -0
  49. package/dist/types/viteConfig.js +6 -0
  50. package/dist/types/viteConfig.js.map +1 -0
  51. package/dist/utils/deepMerge.d.ts +8 -0
  52. package/dist/utils/deepMerge.d.ts.map +1 -0
  53. package/dist/utils/deepMerge.js +33 -0
  54. package/dist/utils/deepMerge.js.map +1 -0
  55. package/dist/utils/ejs.d.ts +19 -0
  56. package/dist/utils/ejs.d.ts.map +1 -0
  57. package/dist/utils/ejs.js +30 -0
  58. package/dist/utils/ejs.js.map +1 -0
  59. package/dist/utils/file.d.ts +70 -0
  60. package/dist/utils/file.d.ts.map +1 -0
  61. package/dist/utils/file.js +119 -0
  62. package/dist/utils/file.js.map +1 -0
  63. package/dist/utils/index.d.ts +12 -0
  64. package/dist/utils/index.d.ts.map +1 -0
  65. package/dist/utils/index.js +12 -0
  66. package/dist/utils/index.js.map +1 -0
  67. package/dist/utils/install.d.ts +17 -0
  68. package/dist/utils/install.d.ts.map +1 -0
  69. package/dist/utils/install.js +37 -0
  70. package/dist/utils/install.js.map +1 -0
  71. package/dist/utils/prompts.d.ts +16 -0
  72. package/dist/utils/prompts.d.ts.map +1 -0
  73. package/dist/utils/prompts.js +180 -0
  74. package/dist/utils/prompts.js.map +1 -0
  75. package/dist/utils/renderFeatures.d.ts +18 -0
  76. package/dist/utils/renderFeatures.d.ts.map +1 -0
  77. package/dist/utils/renderFeatures.js +72 -0
  78. package/dist/utils/renderFeatures.js.map +1 -0
  79. package/dist/utils/renderTemplate.d.ts +6 -0
  80. package/dist/utils/renderTemplate.d.ts.map +1 -0
  81. package/dist/utils/renderTemplate.js +102 -0
  82. package/dist/utils/renderTemplate.js.map +1 -0
  83. package/dist/utils/sortDependencies.d.ts +6 -0
  84. package/dist/utils/sortDependencies.d.ts.map +1 -0
  85. package/dist/utils/sortDependencies.js +22 -0
  86. package/dist/utils/sortDependencies.js.map +1 -0
  87. package/dist/utils/viteConfigRender.d.ts +19 -0
  88. package/dist/utils/viteConfigRender.d.ts.map +1 -0
  89. package/dist/utils/viteConfigRender.js +180 -0
  90. package/dist/utils/viteConfigRender.js.map +1 -0
  91. package/package.json +93 -0
  92. package/templates/common/base/.env +7 -0
  93. package/templates/common/base/.env.development +5 -0
  94. package/templates/common/base/.env.production +5 -0
  95. package/templates/common/base/package.json +56 -0
  96. package/templates/common/base/pnpm-workspace.yaml +37 -0
  97. package/templates/common/base/scripts/build.mts +31 -0
  98. package/templates/common/base/src/apis/index.ts +8 -0
  99. package/templates/common/base/src/apis/request.ts +43 -0
  100. package/templates/common/base/src/apis/services/example.ts +40 -0
  101. package/templates/common/base/src/apis/services/user.ts +23 -0
  102. package/templates/common/base/src/apis/types/common.ts +28 -0
  103. package/templates/common/base/src/apis/types/example.ts +18 -0
  104. package/templates/common/base/src/apis/types/index.ts +7 -0
  105. package/templates/common/base/src/apis/types/user.ts +24 -0
  106. package/templates/common/base/src/assets/fonts/index.css +7 -0
  107. package/templates/common/base/src/assets/styles/base.scss +72 -0
  108. package/templates/common/base/src/assets/styles/custom.scss +7 -0
  109. package/templates/common/base/src/assets/styles/tailwind.scss +6 -0
  110. package/templates/common/base/src/constants/index.ts +29 -0
  111. package/templates/common/base/src/locales/lang/en.ts +30 -0
  112. package/templates/common/base/src/locales/lang/es.ts +30 -0
  113. package/templates/common/base/src/locales/lang/zh.ts +30 -0
  114. package/templates/common/base/src/utils/index.ts +83 -0
  115. package/templates/common/features/husky/.cz-config.cjs +35 -0
  116. package/templates/common/features/husky/.husky/commit-msg +9 -0
  117. package/templates/common/features/husky/.husky/install.mjs +6 -0
  118. package/templates/common/features/husky/.husky/pre-commit +4 -0
  119. package/templates/common/features/husky/commitlint.config.ts +32 -0
  120. package/templates/common/features/husky/package.json +28 -0
  121. package/templates/common/features/husky/pnpm-workspace.yaml +9 -0
  122. package/templates/react/base/env.d.ts +19 -0
  123. package/templates/react/base/index.html +14 -0
  124. package/templates/react/base/package.json +15 -0
  125. package/templates/react/base/pnpm-workspace.yaml +9 -0
  126. package/templates/react/base/src/App.tsx +18 -0
  127. package/templates/react/base/src/assets/styles/main.scss +8 -0
  128. package/templates/react/base/src/main.tsx.ejs +39 -0
  129. package/templates/react/base/src/pages/about/index.tsx +14 -0
  130. package/templates/react/base/src/pages/home/index.tsx +14 -0
  131. package/templates/react/base/src/router/index.tsx.ejs +28 -0
  132. package/templates/react/base/src/stores/user.ts +39 -0
  133. package/templates/react/base/tsconfig.app.json +17 -0
  134. package/templates/react/base/tsconfig.base.json +23 -0
  135. package/templates/react/base/tsconfig.json +12 -0
  136. package/templates/react/base/tsconfig.node.json +15 -0
  137. package/templates/react/base/vite.config.ts +52 -0
  138. package/templates/react/features/ant-design/package.json +7 -0
  139. package/templates/react/features/ant-design/pnpm-workspace.yaml +5 -0
  140. package/templates/react/features/eslint/eslint.config.ts +12 -0
  141. package/templates/react/features/eslint/package.json +7 -0
  142. package/templates/react/features/eslint/pnpm-workspace.yaml +6 -0
  143. package/templates/react/features/i18n/package.json +7 -0
  144. package/templates/react/features/i18n/pnpm-workspace.yaml +5 -0
  145. package/templates/react/features/i18n/src/locales/index.ts +20 -0
  146. package/templates/react/features/manualRoutes/src/router/routes.tsx +21 -0
  147. package/templates/react/features/pageRoutes/package.json +6 -0
  148. package/templates/react/features/pageRoutes/pnpm-workspace.yaml +4 -0
  149. package/templates/react/features/pageRoutes/vite.config.data.ts +10 -0
  150. package/templates/react/features/router/package.json +5 -0
  151. package/templates/react/features/router/pnpm-workspace.yaml +3 -0
  152. package/templates/react/features/sentry/package.json +7 -0
  153. package/templates/react/features/sentry/pnpm-workspace.yaml +5 -0
  154. package/templates/react/features/sentry/src/utils/sentry.ts +30 -0
  155. package/templates/react/features/sentry/vite.config.data.ts +23 -0
  156. package/templates/react/features/zustand/package.json +5 -0
  157. package/templates/react/features/zustand/pnpm-workspace.yaml +3 -0
  158. package/templates/react/features/zustand/src/stores/user.ts +19 -0
  159. package/templates/react/features/zustand/src/types/stores.ts +15 -0
  160. package/templates/vue/base/env.d.ts +27 -0
  161. package/templates/vue/base/index.html +14 -0
  162. package/templates/vue/base/package.json +13 -0
  163. package/templates/vue/base/pnpm-workspace.yaml +6 -0
  164. package/templates/vue/base/src/App.vue +13 -0
  165. package/templates/vue/base/src/assets/styles/element/index.scss +27 -0
  166. package/templates/vue/base/src/assets/styles/main.scss +9 -0
  167. package/templates/vue/base/src/components/SubMenu/index.ts +9 -0
  168. package/templates/vue/base/src/components/SubMenu/src/_types/index.ts +6 -0
  169. package/templates/vue/base/src/components/SubMenu/src/_types/props.ts +11 -0
  170. package/templates/vue/base/src/components/SubMenu/src/index.vue +24 -0
  171. package/templates/vue/base/src/directives/index.ts +36 -0
  172. package/templates/vue/base/src/layouts/AntDesign.vue +86 -0
  173. package/templates/vue/base/src/layouts/element.vue +81 -0
  174. package/templates/vue/base/src/layouts/index.ts +7 -0
  175. package/templates/vue/base/src/main.ts.ejs +100 -0
  176. package/templates/vue/base/src/pages/about/index.vue +31 -0
  177. package/templates/vue/base/src/pages/home/index.vue +31 -0
  178. package/templates/vue/base/src/router/index.ts.ejs +39 -0
  179. package/templates/vue/base/src/stores/index.ts +16 -0
  180. package/templates/vue/base/src/stores/modules/system.ts +52 -0
  181. package/templates/vue/base/src/stores/modules/user.ts +48 -0
  182. package/templates/vue/base/tsconfig.app.json +17 -0
  183. package/templates/vue/base/tsconfig.base.json +23 -0
  184. package/templates/vue/base/tsconfig.json +12 -0
  185. package/templates/vue/base/tsconfig.node.json +15 -0
  186. package/templates/vue/base/vite.config.ts +53 -0
  187. package/templates/vue/features/ant-design-vue/package.json +7 -0
  188. package/templates/vue/features/ant-design-vue/pnpm-workspace.yaml +5 -0
  189. package/templates/vue/features/element-plus/package.json +7 -0
  190. package/templates/vue/features/element-plus/pnpm-workspace.yaml +5 -0
  191. package/templates/vue/features/element-plus/vite.config.data.ts +15 -0
  192. package/templates/vue/features/eslint/eslint.config.ts +12 -0
  193. package/templates/vue/features/eslint/package.json +7 -0
  194. package/templates/vue/features/eslint/pnpm-workspace.yaml +6 -0
  195. package/templates/vue/features/i18n/package.json +5 -0
  196. package/templates/vue/features/i18n/pnpm-workspace.yaml +3 -0
  197. package/templates/vue/features/i18n/src/locales/index.ts +16 -0
  198. package/templates/vue/features/manualRoutes/src/router/layout.vue +10 -0
  199. package/templates/vue/features/manualRoutes/src/router/routes.ts +27 -0
  200. package/templates/vue/features/pageRoutes/package.json +5 -0
  201. package/templates/vue/features/pageRoutes/pnpm-workspace.yaml +4 -0
  202. package/templates/vue/features/pageRoutes/vite.config.data.ts +9 -0
  203. package/templates/vue/features/pinia/package.json +6 -0
  204. package/templates/vue/features/pinia/pnpm-workspace.yaml +4 -0
  205. package/templates/vue/features/pinia/src/stores/index.ts +8 -0
  206. package/templates/vue/features/pinia/src/stores/user.ts +36 -0
  207. package/templates/vue/features/qiankun/package.json +5 -0
  208. package/templates/vue/features/qiankun/pnpm-workspace.yaml +3 -0
  209. package/templates/vue/features/qiankun/src/qiankun/index.ts +56 -0
  210. package/templates/vue/features/router/package.json +5 -0
  211. package/templates/vue/features/router/pnpm-workspace.yaml +3 -0
  212. package/templates/vue/features/sentry/package.json +6 -0
  213. package/templates/vue/features/sentry/pnpm-workspace.yaml +4 -0
  214. package/templates/vue/features/sentry/src/utils/sentry.ts +33 -0
  215. package/templates/vue/features/sentry/vite.config.data.ts +23 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * 示例服务
3
+ * 示例 API 接口
4
+ */
5
+
6
+ import type {
7
+ ApiResponseType,
8
+ CreateExampleParamsType,
9
+ ExampleItemType,
10
+ ListResponseType,
11
+ PaginationParamsType,
12
+ UpdateExampleParamsType,
13
+ } from '../types'
14
+
15
+ import request from '../request'
16
+
17
+ /** 获取示例列表 */
18
+ export function getExampleList(params: PaginationParamsType): Promise<ListResponseType<ExampleItemType>> {
19
+ return request.get('/example/list', { params })
20
+ }
21
+
22
+ /** 获取示例详情 */
23
+ export function getExampleDetail(id: string): Promise<ApiResponseType<ExampleItemType>> {
24
+ return request.get(`/example/${id}`)
25
+ }
26
+
27
+ /** 创建示例 */
28
+ export function createExample(data: CreateExampleParamsType): Promise<ApiResponseType<ExampleItemType>> {
29
+ return request.post('/example', data)
30
+ }
31
+
32
+ /** 更新示例 */
33
+ export function updateExample(id: string, data: UpdateExampleParamsType): Promise<ApiResponseType<ExampleItemType>> {
34
+ return request.put(`/example/${id}`, data)
35
+ }
36
+
37
+ /** 删除示例 */
38
+ export function deleteExample(id: string): Promise<ApiResponseType<null>> {
39
+ return request.delete(`/example/${id}`)
40
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 用户服务
3
+ * 用户相关 API
4
+ */
5
+
6
+ import type { ApiResponseType, LoginParamsType, LoginResponseType, UserInfoType } from '../types'
7
+
8
+ import request from '../request'
9
+
10
+ /** 用户登录 */
11
+ export function login(params: LoginParamsType): Promise<ApiResponseType<LoginResponseType>> {
12
+ return request.post('/auth/login', params)
13
+ }
14
+
15
+ /** 获取用户信息 */
16
+ export function getUserInfo(): Promise<ApiResponseType<UserInfoType>> {
17
+ return request.get('/user/info')
18
+ }
19
+
20
+ /** 用户登出 */
21
+ export function logout(): Promise<ApiResponseType<null>> {
22
+ return request.post('/auth/logout')
23
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 通用类型定义
3
+ * API 响应通用类型
4
+ */
5
+
6
+ /** 分页参数类型 */
7
+ export interface PaginationParamsType {
8
+ page: number
9
+ pageSize: number
10
+ }
11
+
12
+ /** 分页响应类型 */
13
+ export interface PaginationResponseType<T> {
14
+ list: T[]
15
+ total: number
16
+ page: number
17
+ pageSize: number
18
+ }
19
+
20
+ /** 通用响应类型 */
21
+ export interface ApiResponseType<T = unknown> {
22
+ code: number
23
+ message: string
24
+ data: T
25
+ }
26
+
27
+ /** 列表响应类型 */
28
+ export interface ListResponseType<T> extends ApiResponseType<PaginationResponseType<T>> {}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 示例类型定义
3
+ */
4
+
5
+ /** 示例数据类型 */
6
+ export interface ExampleItemType {
7
+ id: string
8
+ name: string
9
+ description: string
10
+ createdAt: string
11
+ }
12
+
13
+ /** 创建示例参数类型 */
14
+ export type CreateExampleParamsType = Omit<ExampleItemType, 'id' | 'createdAt'>
15
+
16
+ /** 更新示例参数类型 */
17
+ export type UpdateExampleParamsType = Partial<ExampleItemType>
18
+
@@ -0,0 +1,7 @@
1
+ /**
2
+ * API 类型导出
3
+ */
4
+
5
+ export * from './common'
6
+ export * from './example'
7
+ export * from './user'
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 用户类型定义
3
+ */
4
+
5
+ /** 用户信息类型 */
6
+ export interface UserInfoType {
7
+ id: string
8
+ username: string
9
+ email: string
10
+ avatar?: string
11
+ roles: string[]
12
+ }
13
+
14
+ /** 登录参数类型 */
15
+ export interface LoginParamsType {
16
+ username: string
17
+ password: string
18
+ }
19
+
20
+ /** 登录响应类型 */
21
+ export interface LoginResponseType {
22
+ token: string
23
+ userInfo: UserInfoType
24
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 字体配置
3
+ * 自定义字体导入
4
+ */
5
+
6
+ /* 可在此添加自定义字体 */
7
+
@@ -0,0 +1,72 @@
1
+ /**
2
+ * 基础样式
3
+ * CSS Reset 和全局基础样式
4
+ */
5
+
6
+ *,
7
+ *::before,
8
+ *::after {
9
+ box-sizing: border-box;
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+
14
+ html {
15
+ font-size: 16px;
16
+ line-height: 1.5;
17
+ -webkit-font-smoothing: antialiased;
18
+ -moz-osx-font-smoothing: grayscale;
19
+ }
20
+
21
+ body {
22
+ min-height: 100vh;
23
+ font-family:
24
+ -apple-system,
25
+ BlinkMacSystemFont,
26
+ 'Segoe UI',
27
+ Roboto,
28
+ 'Helvetica Neue',
29
+ Arial,
30
+ sans-serif;
31
+ }
32
+
33
+ img,
34
+ picture,
35
+ video,
36
+ canvas,
37
+ svg {
38
+ display: block;
39
+ max-width: 100%;
40
+ }
41
+
42
+ input,
43
+ button,
44
+ textarea,
45
+ select {
46
+ font: inherit;
47
+ }
48
+
49
+ p,
50
+ h1,
51
+ h2,
52
+ h3,
53
+ h4,
54
+ h5,
55
+ h6 {
56
+ overflow-wrap: break-word;
57
+ }
58
+
59
+ a {
60
+ color: inherit;
61
+ text-decoration: none;
62
+ }
63
+
64
+ ul,
65
+ ol {
66
+ list-style: none;
67
+ }
68
+
69
+ #app {
70
+ min-height: 100vh;
71
+ }
72
+
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 自定义样式
3
+ * 项目特定的全局样式
4
+ */
5
+
6
+ // 可在此添加项目特定的全局样式
7
+
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tailwind CSS 配置
3
+ */
4
+
5
+ @import 'tailwindcss';
6
+
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 常量定义
3
+ * 项目通用常量
4
+ */
5
+
6
+ /** 本地存储键名 */
7
+ export const STORAGE_KEYS = {
8
+ TOKEN: 'token',
9
+ USER_INFO: 'userInfo',
10
+ LANGUAGE: 'language',
11
+ THEME: 'theme',
12
+ } as const;
13
+
14
+ /** 响应码 */
15
+ export const RESPONSE_CODE = {
16
+ SUCCESS: 200,
17
+ UNAUTHORIZED: 401,
18
+ FORBIDDEN: 403,
19
+ NOT_FOUND: 404,
20
+ SERVER_ERROR: 500,
21
+ } as const;
22
+
23
+ /** 分页默认配置 */
24
+ export const PAGINATION = {
25
+ DEFAULT_PAGE: 1,
26
+ DEFAULT_PAGE_SIZE: 10,
27
+ PAGE_SIZE_OPTIONS: [10, 20, 50, 100],
28
+ } as const;
29
+
@@ -0,0 +1,30 @@
1
+ /**
2
+ * English Language Pack
3
+ */
4
+
5
+ export default {
6
+ common: {
7
+ confirm: 'Confirm',
8
+ cancel: 'Cancel',
9
+ save: 'Save',
10
+ delete: 'Delete',
11
+ edit: 'Edit',
12
+ add: 'Add',
13
+ search: 'Search',
14
+ reset: 'Reset',
15
+ loading: 'Loading...',
16
+ success: 'Success',
17
+ error: 'Error',
18
+ },
19
+ menu: {
20
+ home: 'Home',
21
+ about: 'About',
22
+ },
23
+ user: {
24
+ login: 'Login',
25
+ logout: 'Logout',
26
+ username: 'Username',
27
+ password: 'Password',
28
+ },
29
+ };
30
+
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Spanish Language Pack
3
+ */
4
+
5
+ export default {
6
+ common: {
7
+ confirm: 'Confirmar',
8
+ cancel: 'Cancelar',
9
+ save: 'Guardar',
10
+ delete: 'Eliminar',
11
+ edit: 'Editar',
12
+ add: 'Agregar',
13
+ search: 'Buscar',
14
+ reset: 'Restablecer',
15
+ loading: 'Cargando...',
16
+ success: 'Éxito',
17
+ error: 'Error',
18
+ },
19
+ menu: {
20
+ home: 'Inicio',
21
+ about: 'Acerca de',
22
+ },
23
+ user: {
24
+ login: 'Iniciar sesión',
25
+ logout: 'Cerrar sesión',
26
+ username: 'Nombre de usuario',
27
+ password: 'Contraseña',
28
+ },
29
+ };
30
+
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 中文语言包
3
+ */
4
+
5
+ export default {
6
+ common: {
7
+ confirm: '确认',
8
+ cancel: '取消',
9
+ save: '保存',
10
+ delete: '删除',
11
+ edit: '编辑',
12
+ add: '新增',
13
+ search: '搜索',
14
+ reset: '重置',
15
+ loading: '加载中...',
16
+ success: '操作成功',
17
+ error: '操作失败',
18
+ },
19
+ menu: {
20
+ home: '首页',
21
+ about: '关于',
22
+ },
23
+ user: {
24
+ login: '登录',
25
+ logout: '退出登录',
26
+ username: '用户名',
27
+ password: '密码',
28
+ },
29
+ };
30
+
@@ -0,0 +1,83 @@
1
+ /**
2
+ * 工具函数
3
+ * 通用工具方法
4
+ */
5
+
6
+ /**
7
+ * 延迟执行
8
+ * @param ms 延迟毫秒数
9
+ */
10
+ export function sleep(ms: number): Promise<void> {
11
+ return new Promise((resolve) => setTimeout(resolve, ms));
12
+ }
13
+
14
+ /**
15
+ * 深拷贝
16
+ * @param obj 要拷贝的对象
17
+ */
18
+ export function deepClone<T>(obj: T): T {
19
+ return JSON.parse(JSON.stringify(obj));
20
+ }
21
+
22
+ /**
23
+ * 防抖函数
24
+ * @param fn 要防抖的函数
25
+ * @param delay 延迟时间
26
+ */
27
+ export function debounce<T extends (...args: unknown[]) => unknown>(
28
+ fn: T,
29
+ delay: number
30
+ ): (...args: Parameters<T>) => void {
31
+ let timer: ReturnType<typeof setTimeout> | null = null;
32
+ return function (this: unknown, ...args: Parameters<T>) {
33
+ if (timer) {
34
+ clearTimeout(timer);
35
+ }
36
+ timer = setTimeout(() => {
37
+ fn.apply(this, args);
38
+ }, delay);
39
+ };
40
+ }
41
+
42
+ /**
43
+ * 节流函数
44
+ * @param fn 要节流的函数
45
+ * @param delay 间隔时间
46
+ */
47
+ export function throttle<T extends (...args: unknown[]) => unknown>(
48
+ fn: T,
49
+ delay: number
50
+ ): (...args: Parameters<T>) => void {
51
+ let lastTime = 0;
52
+ return function (this: unknown, ...args: Parameters<T>) {
53
+ const now = Date.now();
54
+ if (now - lastTime >= delay) {
55
+ lastTime = now;
56
+ fn.apply(this, args);
57
+ }
58
+ };
59
+ }
60
+
61
+ /**
62
+ * 格式化日期
63
+ * @param date 日期
64
+ * @param format 格式
65
+ */
66
+ export function formatDate(date: Date | string | number, format = 'YYYY-MM-DD HH:mm:ss'): string {
67
+ const d = new Date(date);
68
+ const year = d.getFullYear();
69
+ const month = String(d.getMonth() + 1).padStart(2, '0');
70
+ const day = String(d.getDate()).padStart(2, '0');
71
+ const hours = String(d.getHours()).padStart(2, '0');
72
+ const minutes = String(d.getMinutes()).padStart(2, '0');
73
+ const seconds = String(d.getSeconds()).padStart(2, '0');
74
+
75
+ return format
76
+ .replace('YYYY', String(year))
77
+ .replace('MM', month)
78
+ .replace('DD', day)
79
+ .replace('HH', hours)
80
+ .replace('mm', minutes)
81
+ .replace('ss', seconds);
82
+ }
83
+
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Commitizen 自定义配置
3
+ * 定义 commit 类型和提交规范
4
+ */
5
+
6
+ module.exports = {
7
+ types: [
8
+ { value: 'feat', name: 'feat: ✨ 新功能' },
9
+ { value: 'fix', name: 'fix: 🐛 修复 Bug' },
10
+ { value: 'docs', name: 'docs: 📝 文档更新' },
11
+ { value: 'style', name: 'style: 💄 代码格式(不影响功能)' },
12
+ { value: 'refactor', name: 'refactor: ♻️ 代码重构' },
13
+ { value: 'perf', name: 'perf: ⚡ 性能优化' },
14
+ { value: 'test', name: 'test: ✅ 测试相关' },
15
+ { value: 'build', name: 'build: 📦 构建相关' },
16
+ { value: 'ci', name: 'ci: 🔧 CI 配置' },
17
+ { value: 'chore', name: 'chore: 🔨 其他修改' },
18
+ { value: 'revert', name: 'revert: ⏪ 回退' },
19
+ ],
20
+ scopes: [],
21
+ messages: {
22
+ type: '请选择提交类型:',
23
+ scope: '请输入修改范围(可选):',
24
+ customScope: '请输入自定义修改范围:',
25
+ subject: '请简要描述提交(必填):',
26
+ body: '请输入详细描述(可选):',
27
+ breaking: '列出任何破坏性变更(可选):',
28
+ footer: '请输入要关闭的 issue(可选):',
29
+ confirmCommit: '确认使用以上信息提交?',
30
+ },
31
+ allowCustomScopes: true,
32
+ allowBreakingChanges: ['feat', 'fix'],
33
+ skipQuestions: ['scope', 'body', 'breaking', 'footer'],
34
+ subjectLimit: 100,
35
+ }
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ COMMIT_LOCATION="${PWD}/.git/COMMIT_EDITMSG"
5
+ if [ -f "$COMMIT_LOCATION" ]; then
6
+ npx --no-install commitlint --edit "${COMMIT_LOCATION}"
7
+ else
8
+ npx --no-install commitlint --edit "$1"
9
+ fi
@@ -0,0 +1,6 @@
1
+ // Skip Husky install in production and CI
2
+ if (process.env.NODE_ENV === 'production' || process.env.CI === 'true') {
3
+ process.exit(0)
4
+ }
5
+ const husky = (await import('husky')).default
6
+ console.log(husky())
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ pnpm lint-staged
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Commitlint 配置
3
+ * 验证 commit message 格式
4
+ */
5
+
6
+ import type { UserConfig } from '@commitlint/types'
7
+
8
+ const config: UserConfig = {
9
+ extends: ['@commitlint/config-conventional'],
10
+ rules: {
11
+ 'type-enum': [
12
+ 2,
13
+ 'always',
14
+ [
15
+ 'feat',
16
+ 'fix',
17
+ 'docs',
18
+ 'style',
19
+ 'refactor',
20
+ 'perf',
21
+ 'test',
22
+ 'build',
23
+ 'ci',
24
+ 'chore',
25
+ 'revert',
26
+ ],
27
+ ],
28
+ 'subject-case': [0],
29
+ },
30
+ }
31
+
32
+ export default config
@@ -0,0 +1,28 @@
1
+ {
2
+ "scripts": {
3
+ "prepare": "node .husky/install.mjs",
4
+ "lint-staged": "lint-staged",
5
+ "commit": "git add . && git-cz"
6
+ },
7
+ "lint-staged": {
8
+ "*.{js,jsx,ts,tsx,vue,css,scss,less}": [
9
+ "eslint --fix --no-warn-ignored"
10
+ ]
11
+ },
12
+ "config": {
13
+ "commitizen": {
14
+ "path": "cz-customizable"
15
+ },
16
+ "cz-customizable": {
17
+ "config": ".cz-config.cjs"
18
+ }
19
+ },
20
+ "devDependencies": {
21
+ "@commitlint/cli": "catalog:dev",
22
+ "@commitlint/config-conventional": "catalog:dev",
23
+ "commitizen": "catalog:dev",
24
+ "cz-customizable": "catalog:dev",
25
+ "husky": "catalog:dev",
26
+ "lint-staged": "catalog:dev"
27
+ }
28
+ }
@@ -0,0 +1,9 @@
1
+ catalogs:
2
+ dev:
3
+ "@commitlint/cli": ^19.8.0
4
+ "@commitlint/config-conventional": ^19.8.0
5
+ commitizen: ^4.3.1
6
+ cz-customizable: ^7.4.0
7
+ husky: ^9.1.7
8
+ lint-staged: ^15.5.1
9
+
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 环境变量类型声明
3
+ */
4
+
5
+ /// <reference types="vite/client" />
6
+
7
+ interface ImportMetaEnv {
8
+ readonly VITE_APP_CODE: string
9
+ readonly VITE_APP_TITLE: string
10
+ readonly VITE_APP_PORT: number
11
+ readonly VITE_APP_VERSION: string
12
+ readonly VITE_APP_ENV: string
13
+ readonly VITE_API_BASE_URL: string
14
+ readonly VITE_SENTRY: boolean
15
+ }
16
+
17
+ interface ImportMeta {
18
+ readonly env: ImportMetaEnv
19
+ }
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>%VITE_APP_TITLE%</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
14
+
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "react-project",
3
+ "scripts": {
4
+ "type-check": "tsc --noEmit"
5
+ },
6
+ "dependencies": {
7
+ "react": "catalog:build",
8
+ "react-dom": "catalog:build"
9
+ },
10
+ "devDependencies": {
11
+ "@types/react": "catalog:type",
12
+ "@types/react-dom": "catalog:type",
13
+ "@vitejs/plugin-react": "catalog:dev"
14
+ }
15
+ }
@@ -0,0 +1,9 @@
1
+ catalogs:
2
+ build:
3
+ react: ^18.3.1
4
+ react-dom: ^18.3.1
5
+ dev:
6
+ "@vitejs/plugin-react": ^4.3.4
7
+ type:
8
+ "@types/react": ^18.3.12
9
+ "@types/react-dom": ^18.3.1
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 根组件
3
+ */
4
+
5
+ import { Route, Routes } from 'react-router-dom'
6
+ import Home from '@/pages/home'
7
+ import About from '@/pages/about'
8
+
9
+ function App(): JSX.Element {
10
+ return (
11
+ <Routes>
12
+ <Route path="/" element={<Home />} />
13
+ <Route path="/about" element={<About />} />
14
+ </Routes>
15
+ )
16
+ }
17
+
18
+ export default App
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 主样式文件
3
+ * 导入所有样式
4
+ */
5
+
6
+ @import './base.scss';
7
+ @import './custom.scss';
8
+ @import './tailwind.scss';