create-project-template-cli 1.0.0

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 (69) hide show
  1. package/README.md +5 -0
  2. package/index.js +133 -0
  3. package/package.json +33 -0
  4. package/template/react-shadcn/.husky/commit-msg +4 -0
  5. package/template/react-shadcn/.husky/pre-commit +1 -0
  6. package/template/react-shadcn/.stylelintignore +20 -0
  7. package/template/react-shadcn/.stylelintrc.cjs +258 -0
  8. package/template/react-shadcn/.vscode/extensions.json +7 -0
  9. package/template/react-shadcn/README.md +75 -0
  10. package/template/react-shadcn/commitlint.config.cjs +90 -0
  11. package/template/react-shadcn/components.json +22 -0
  12. package/template/react-shadcn/eslint.config.js +58 -0
  13. package/template/react-shadcn/index.html +13 -0
  14. package/template/react-shadcn/lint-staged.config.cjs +4 -0
  15. package/template/react-shadcn/package.json +62 -0
  16. package/template/react-shadcn/pnpm-lock.yaml +4514 -0
  17. package/template/react-shadcn/public/vite.svg +1 -0
  18. package/template/react-shadcn/src/App.css +23 -0
  19. package/template/react-shadcn/src/App.tsx +20 -0
  20. package/template/react-shadcn/src/assets/css/tailwindcss.css +120 -0
  21. package/template/react-shadcn/src/assets/react.svg +1 -0
  22. package/template/react-shadcn/src/components/ui/button.tsx +58 -0
  23. package/template/react-shadcn/src/components/ui/card.tsx +92 -0
  24. package/template/react-shadcn/src/components/ui/input.tsx +21 -0
  25. package/template/react-shadcn/src/components/ui/label.tsx +22 -0
  26. package/template/react-shadcn/src/components/ui/navigation-menu.tsx +168 -0
  27. package/template/react-shadcn/src/lib/utils.ts +6 -0
  28. package/template/react-shadcn/src/main.tsx +11 -0
  29. package/template/react-shadcn/src/router/index.tsx +71 -0
  30. package/template/react-shadcn/src/views/404/index.scss +133 -0
  31. package/template/react-shadcn/src/views/404/index.tsx +27 -0
  32. package/template/react-shadcn/src/views/Index/index.tsx +8 -0
  33. package/template/react-shadcn/src/views/index.tsx +59 -0
  34. package/template/react-shadcn/tsconfig.app.json +33 -0
  35. package/template/react-shadcn/tsconfig.json +13 -0
  36. package/template/react-shadcn/tsconfig.node.json +32 -0
  37. package/template/react-shadcn/vite.config.ts +36 -0
  38. package/template/vue-tailwindcss/.editorconfig +8 -0
  39. package/template/vue-tailwindcss/.eslintrc-auto-import.json +76 -0
  40. package/template/vue-tailwindcss/.gitattributes +1 -0
  41. package/template/vue-tailwindcss/.prettierrc.json +6 -0
  42. package/template/vue-tailwindcss/.vscode/extensions.json +9 -0
  43. package/template/vue-tailwindcss/README.md +2 -0
  44. package/template/vue-tailwindcss/env.d.ts +1 -0
  45. package/template/vue-tailwindcss/eslint.config.ts +90 -0
  46. package/template/vue-tailwindcss/index.html +13 -0
  47. package/template/vue-tailwindcss/package.json +53 -0
  48. package/template/vue-tailwindcss/pnpm-lock.yaml +5021 -0
  49. package/template/vue-tailwindcss/public/favicon.ico +0 -0
  50. package/template/vue-tailwindcss/src/App.vue +83 -0
  51. package/template/vue-tailwindcss/src/assets/base.css +86 -0
  52. package/template/vue-tailwindcss/src/assets/logo.svg +1 -0
  53. package/template/vue-tailwindcss/src/assets/main.css +10 -0
  54. package/template/vue-tailwindcss/src/auto-import.d.ts +71 -0
  55. package/template/vue-tailwindcss/src/axios/index.ts +107 -0
  56. package/template/vue-tailwindcss/src/components.d.ts +22 -0
  57. package/template/vue-tailwindcss/src/main.ts +14 -0
  58. package/template/vue-tailwindcss/src/router/index.ts +23 -0
  59. package/template/vue-tailwindcss/src/stores/counter.ts +12 -0
  60. package/template/vue-tailwindcss/src/views/AboutView.vue +15 -0
  61. package/template/vue-tailwindcss/src/views/HomeView.vue +7 -0
  62. package/template/vue-tailwindcss/src/vite-env.d.ts +6 -0
  63. package/template/vue-tailwindcss/tsconfig.app.json +14 -0
  64. package/template/vue-tailwindcss/tsconfig.json +14 -0
  65. package/template/vue-tailwindcss/tsconfig.node.json +34 -0
  66. package/template/vue-tailwindcss/tsconfig.vitest.json +11 -0
  67. package/template/vue-tailwindcss/vite.config.ts +33 -0
  68. package/template/vue-tailwindcss/vitest.config.ts +14 -0
  69. package/utils.js +73 -0
@@ -0,0 +1,83 @@
1
+ <script setup lang="ts">
2
+ import { RouterLink, RouterView } from 'vue-router'
3
+ </script>
4
+
5
+ <template>
6
+ <header>
7
+ <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
8
+
9
+ <div class="wrapper">
10
+ <nav>
11
+ <RouterLink to="/">Home</RouterLink>
12
+ <RouterLink to="/about">About</RouterLink>
13
+ </nav>
14
+ <div class="text-2xl font-bold">tailwindcss</div>
15
+ </div>
16
+ </header>
17
+
18
+ <RouterView />
19
+ </template>
20
+
21
+ <style scoped lang="scss">
22
+ header {
23
+ line-height: 1.5;
24
+ max-height: 100vh;
25
+ }
26
+
27
+ .logo {
28
+ display: block;
29
+ margin: 0 auto 2rem;
30
+ }
31
+
32
+ nav {
33
+ width: 100%;
34
+ font-size: 12px;
35
+ text-align: center;
36
+ margin-top: 2rem;
37
+ }
38
+
39
+ nav a.router-link-exact-active {
40
+ color: var(--color-text);
41
+ }
42
+
43
+ nav a.router-link-exact-active:hover {
44
+ background-color: transparent;
45
+ }
46
+
47
+ nav a {
48
+ display: inline-block;
49
+ padding: 0 1rem;
50
+ border-left: 1px solid var(--color-border);
51
+ }
52
+
53
+ nav a:first-of-type {
54
+ border: 0;
55
+ }
56
+
57
+ @media (min-width: 1024px) {
58
+ header {
59
+ display: flex;
60
+ place-items: center;
61
+ padding-right: calc(var(--section-gap) / 2);
62
+ }
63
+
64
+ .logo {
65
+ margin: 0 2rem 0 0;
66
+ }
67
+
68
+ header .wrapper {
69
+ display: flex;
70
+ place-items: flex-start;
71
+ flex-wrap: wrap;
72
+ }
73
+
74
+ nav {
75
+ text-align: left;
76
+ margin-left: -1rem;
77
+ font-size: 1rem;
78
+
79
+ padding: 1rem 0;
80
+ margin-top: 1rem;
81
+ }
82
+ }
83
+ </style>
@@ -0,0 +1,86 @@
1
+ /* color palette from <https://github.com/vuejs/theme> */
2
+ :root {
3
+ --vt-c-white: #ffffff;
4
+ --vt-c-white-soft: #f8f8f8;
5
+ --vt-c-white-mute: #f2f2f2;
6
+
7
+ --vt-c-black: #181818;
8
+ --vt-c-black-soft: #222222;
9
+ --vt-c-black-mute: #282828;
10
+
11
+ --vt-c-indigo: #2c3e50;
12
+
13
+ --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
14
+ --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
15
+ --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
16
+ --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
17
+
18
+ --vt-c-text-light-1: var(--vt-c-indigo);
19
+ --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
20
+ --vt-c-text-dark-1: var(--vt-c-white);
21
+ --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
22
+ }
23
+
24
+ /* semantic color variables for this project */
25
+ :root {
26
+ --color-background: var(--vt-c-white);
27
+ --color-background-soft: var(--vt-c-white-soft);
28
+ --color-background-mute: var(--vt-c-white-mute);
29
+
30
+ --color-border: var(--vt-c-divider-light-2);
31
+ --color-border-hover: var(--vt-c-divider-light-1);
32
+
33
+ --color-heading: var(--vt-c-text-light-1);
34
+ --color-text: var(--vt-c-text-light-1);
35
+
36
+ --section-gap: 160px;
37
+ }
38
+
39
+ @media (prefers-color-scheme: dark) {
40
+ :root {
41
+ --color-background: var(--vt-c-black);
42
+ --color-background-soft: var(--vt-c-black-soft);
43
+ --color-background-mute: var(--vt-c-black-mute);
44
+
45
+ --color-border: var(--vt-c-divider-dark-2);
46
+ --color-border-hover: var(--vt-c-divider-dark-1);
47
+
48
+ --color-heading: var(--vt-c-text-dark-1);
49
+ --color-text: var(--vt-c-text-dark-2);
50
+ }
51
+ }
52
+
53
+ *,
54
+ *::before,
55
+ *::after {
56
+ box-sizing: border-box;
57
+ margin: 0;
58
+ font-weight: normal;
59
+ }
60
+
61
+ body {
62
+ min-height: 100vh;
63
+ color: var(--color-text);
64
+ background: var(--color-background);
65
+ transition:
66
+ color 0.5s,
67
+ background-color 0.5s;
68
+ line-height: 1.6;
69
+ font-family:
70
+ Inter,
71
+ -apple-system,
72
+ BlinkMacSystemFont,
73
+ 'Segoe UI',
74
+ Roboto,
75
+ Oxygen,
76
+ Ubuntu,
77
+ Cantarell,
78
+ 'Fira Sans',
79
+ 'Droid Sans',
80
+ 'Helvetica Neue',
81
+ sans-serif;
82
+ font-size: 15px;
83
+ text-rendering: optimizeLegibility;
84
+ -webkit-font-smoothing: antialiased;
85
+ -moz-osx-font-smoothing: grayscale;
86
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
@@ -0,0 +1,10 @@
1
+ @import "tailwindcss";
2
+ @import './base.css';
3
+
4
+ #app {
5
+ width: 100%;
6
+ height: 100%;
7
+ }
8
+
9
+
10
+
@@ -0,0 +1,71 @@
1
+ /* eslint-disable */
2
+ /* prettier-ignore */
3
+ // @ts-nocheck
4
+ // noinspection JSUnusedGlobalSymbols
5
+ // Generated by unplugin-auto-import
6
+ // biome-ignore lint: disable
7
+ export {}
8
+ declare global {
9
+ const EffectScope: typeof import('vue')['EffectScope']
10
+ const computed: typeof import('vue')['computed']
11
+ const createApp: typeof import('vue')['createApp']
12
+ const customRef: typeof import('vue')['customRef']
13
+ const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
14
+ const defineComponent: typeof import('vue')['defineComponent']
15
+ const effectScope: typeof import('vue')['effectScope']
16
+ const getCurrentInstance: typeof import('vue')['getCurrentInstance']
17
+ const getCurrentScope: typeof import('vue')['getCurrentScope']
18
+ const h: typeof import('vue')['h']
19
+ const inject: typeof import('vue')['inject']
20
+ const isProxy: typeof import('vue')['isProxy']
21
+ const isReactive: typeof import('vue')['isReactive']
22
+ const isReadonly: typeof import('vue')['isReadonly']
23
+ const isRef: typeof import('vue')['isRef']
24
+ const markRaw: typeof import('vue')['markRaw']
25
+ const nextTick: typeof import('vue')['nextTick']
26
+ const onActivated: typeof import('vue')['onActivated']
27
+ const onBeforeMount: typeof import('vue')['onBeforeMount']
28
+ const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
29
+ const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
30
+ const onDeactivated: typeof import('vue')['onDeactivated']
31
+ const onErrorCaptured: typeof import('vue')['onErrorCaptured']
32
+ const onMounted: typeof import('vue')['onMounted']
33
+ const onRenderTracked: typeof import('vue')['onRenderTracked']
34
+ const onRenderTriggered: typeof import('vue')['onRenderTriggered']
35
+ const onScopeDispose: typeof import('vue')['onScopeDispose']
36
+ const onServerPrefetch: typeof import('vue')['onServerPrefetch']
37
+ const onUnmounted: typeof import('vue')['onUnmounted']
38
+ const onUpdated: typeof import('vue')['onUpdated']
39
+ const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
40
+ const provide: typeof import('vue')['provide']
41
+ const reactive: typeof import('vue')['reactive']
42
+ const readonly: typeof import('vue')['readonly']
43
+ const ref: typeof import('vue')['ref']
44
+ const resolveComponent: typeof import('vue')['resolveComponent']
45
+ const shallowReactive: typeof import('vue')['shallowReactive']
46
+ const shallowReadonly: typeof import('vue')['shallowReadonly']
47
+ const shallowRef: typeof import('vue')['shallowRef']
48
+ const toRaw: typeof import('vue')['toRaw']
49
+ const toRef: typeof import('vue')['toRef']
50
+ const toRefs: typeof import('vue')['toRefs']
51
+ const toValue: typeof import('vue')['toValue']
52
+ const triggerRef: typeof import('vue')['triggerRef']
53
+ const unref: typeof import('vue')['unref']
54
+ const useAttrs: typeof import('vue')['useAttrs']
55
+ const useCssModule: typeof import('vue')['useCssModule']
56
+ const useCssVars: typeof import('vue')['useCssVars']
57
+ const useId: typeof import('vue')['useId']
58
+ const useModel: typeof import('vue')['useModel']
59
+ const useSlots: typeof import('vue')['useSlots']
60
+ const useTemplateRef: typeof import('vue')['useTemplateRef']
61
+ const watch: typeof import('vue')['watch']
62
+ const watchEffect: typeof import('vue')['watchEffect']
63
+ const watchPostEffect: typeof import('vue')['watchPostEffect']
64
+ const watchSyncEffect: typeof import('vue')['watchSyncEffect']
65
+ }
66
+ // for type re-export
67
+ declare global {
68
+ // @ts-ignore
69
+ export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
70
+ import('vue')
71
+ }
@@ -0,0 +1,107 @@
1
+ import axios from 'axios'
2
+
3
+ import router from '../router/index'
4
+ // import { isEqual } from 'lodash-es'
5
+ const request = axios.create({
6
+ baseURL: import.meta.env.VITE_BASE_URL,
7
+ timeout: 5000,
8
+ headers: {
9
+ Authorization: JSON.parse(localStorage.getItem('userInfo') || '{}')['token-web'] || '',
10
+ noToken: true,
11
+ },
12
+ })
13
+ const newSet = new Set()
14
+ // 将请求地址和请求参数和方法生成一个字符串
15
+ const genKey = (config: any) => {
16
+ const { method, url, data } = config
17
+
18
+ return data
19
+ ? [
20
+ url,
21
+ method,
22
+ typeof data !== 'string' ? JSON.stringify(data) : JSON.stringify(JSON.parse(data)),
23
+ ].join('&')
24
+ : [url, method].join('&')
25
+ }
26
+ // 添加请求拦截器
27
+ request.interceptors.request.use(
28
+ (config: any) => {
29
+ // 获取请求地址和请求参数
30
+ const key = genKey(config)
31
+
32
+ // 每次请求前读取newSet中有没有key
33
+ if (newSet.has(key)) {
34
+ // 如果有,说明重复请求,返回一个错误
35
+ return Promise.reject('重复请求')
36
+ }
37
+ // 如果没有,将key添加到newSet中
38
+ newSet.add(key)
39
+ const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
40
+ config.headers.Authorization = 'Bear ' + userInfo['token-web'] || ''
41
+ return config
42
+ },
43
+ (error) => {
44
+ // 对请求错误做些什么
45
+ return Promise.reject(error)
46
+ },
47
+ )
48
+ // 添加响应拦截器
49
+ request.interceptors.response.use(
50
+ (response) => {
51
+ // 对响应数据做点什么
52
+
53
+ const key = genKey(response.config)
54
+ // 每次请求后删除newSet中的key
55
+ newSet.delete(key)
56
+
57
+ const res = response.data
58
+ // console.log(response)
59
+ if (res.code && res.code !== 0) {
60
+ // `token` 过期或者账号已在别处登录
61
+ if (res.code === 401 || res.code === 4001) {
62
+ router.push('/login')
63
+ }
64
+
65
+ return res
66
+ } else {
67
+ return res
68
+ }
69
+ },
70
+ (error) => {
71
+ if (error === '重复请求') {
72
+ return Promise.reject('重复请求')
73
+ }
74
+ console.log(error)
75
+ const key = genKey(error.config)
76
+ // 每次请求后删除newSet中的key
77
+ newSet.delete(key)
78
+ console.log('添加响应拦截器')
79
+ if (error.message === 'canceled') {
80
+ return Promise.reject('取消请求')
81
+ }
82
+ if (error.response.data && error.response.data.message) {
83
+ return error.response.data
84
+ } else {
85
+ if (error.response.status === 401) {
86
+ localStorage.clear()
87
+
88
+ return
89
+ }
90
+
91
+ // 对响应错误做点什么
92
+ if (error.message.indexOf('timeout') != -1) {
93
+ console.log('网络超时')
94
+ } else if (error.message == 'Network Error') {
95
+ console.log('网络连接错误')
96
+ } else {
97
+ if (error.response.data) console.log(error.response.data.message)
98
+ else console.log('接口路径找不到')
99
+ // ElMessage.error(error.message)
100
+ }
101
+ return Promise.reject(error)
102
+ }
103
+ },
104
+ )
105
+
106
+ // 导出 axios 实例
107
+ export default request
@@ -0,0 +1,22 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ // Generated by unplugin-vue-components
4
+ // Read more: https://github.com/vuejs/core/pull/3399
5
+ // biome-ignore lint: disable
6
+ export {}
7
+
8
+ /* prettier-ignore */
9
+ declare module 'vue' {
10
+ export interface GlobalComponents {
11
+ HelloWorld: typeof import('./components/HelloWorld.vue')['default']
12
+ IconCommunity: typeof import('./components/icons/IconCommunity.vue')['default']
13
+ IconDocumentation: typeof import('./components/icons/IconDocumentation.vue')['default']
14
+ IconEcosystem: typeof import('./components/icons/IconEcosystem.vue')['default']
15
+ IconSupport: typeof import('./components/icons/IconSupport.vue')['default']
16
+ IconTooling: typeof import('./components/icons/IconTooling.vue')['default']
17
+ RouterLink: typeof import('vue-router')['RouterLink']
18
+ RouterView: typeof import('vue-router')['RouterView']
19
+ TheWelcome: typeof import('./components/TheWelcome.vue')['default']
20
+ WelcomeItem: typeof import('./components/WelcomeItem.vue')['default']
21
+ }
22
+ }
@@ -0,0 +1,14 @@
1
+ import './assets/main.css'
2
+
3
+ import { createApp } from 'vue'
4
+ import { createPinia } from 'pinia'
5
+
6
+ import App from './App.vue'
7
+ import router from './router'
8
+
9
+ const app = createApp(App)
10
+
11
+ app.use(createPinia())
12
+ app.use(router)
13
+
14
+ app.mount('#app')
@@ -0,0 +1,23 @@
1
+ import { createRouter, createWebHistory } from 'vue-router'
2
+ import HomeView from '../views/HomeView.vue'
3
+
4
+ const router = createRouter({
5
+ history: createWebHistory(import.meta.env.BASE_URL),
6
+ routes: [
7
+ {
8
+ path: '/',
9
+ name: 'home',
10
+ component: HomeView,
11
+ },
12
+ {
13
+ path: '/about',
14
+ name: 'about',
15
+ // route level code-splitting
16
+ // this generates a separate chunk (About.[hash].js) for this route
17
+ // which is lazy-loaded when the route is visited.
18
+ component: () => import('../views/AboutView.vue'),
19
+ },
20
+ ],
21
+ })
22
+
23
+ export default router
@@ -0,0 +1,12 @@
1
+ import { ref, computed } from 'vue'
2
+ import { defineStore } from 'pinia'
3
+
4
+ export const useCounterStore = defineStore('counter', () => {
5
+ const count = ref(0)
6
+ const doubleCount = computed(() => count.value * 2)
7
+ function increment() {
8
+ count.value++
9
+ }
10
+
11
+ return { count, doubleCount, increment }
12
+ })
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div class="about">
3
+ <h1>This is an about page</h1>
4
+ </div>
5
+ </template>
6
+
7
+ <style>
8
+ @media (min-width: 1024px) {
9
+ .about {
10
+ min-height: 100vh;
11
+ display: flex;
12
+ align-items: center;
13
+ }
14
+ }
15
+ </style>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts"></script>
2
+
3
+ <template>
4
+ <main>
5
+ <div>home</div>
6
+ </main>
7
+ </template>
@@ -0,0 +1,6 @@
1
+ /// <reference types="vite/client" />
2
+ // TODO: TS 无法主动发现模块,如果找不到模块,则需要在此使用 declare module 进行配置
3
+ declare module 'element-plus/dist/locale/zh-cn.mjs'
4
+ declare module '*.vue'
5
+ declare module '*.js'
6
+ declare module 'lodash-es'
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
3
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
4
+ "exclude": ["src/**/__tests__/*"],
5
+ "compilerOptions": {
6
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
7
+ "lib": ["ESNext", "DOM"],
8
+ // 配置@别名
9
+ "baseUrl": ".",
10
+ "paths": {
11
+ "@/*": ["src/*"]
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ {
5
+ "path": "./tsconfig.node.json"
6
+ },
7
+ {
8
+ "path": "./tsconfig.app.json"
9
+ },
10
+ {
11
+ "path": "./tsconfig.vitest.json"
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "extends": "@tsconfig/node22/tsconfig.json",
3
+ "include": [
4
+ "vite.config.*",
5
+ "vitest.config.*",
6
+ "cypress.config.*",
7
+ "nightwatch.conf.*",
8
+ "playwright.config.*",
9
+ "eslint.config.*",
10
+ "vite.config.ts",
11
+ "src/**/*.ts",
12
+ "src/**/*.d.ts",
13
+ "src/**/*.tsx",
14
+ "src/**/*.vue",
15
+ "components.d.ts",
16
+ "auto-imports.d.ts",
17
+ "env.d.ts"
18
+ ],
19
+ "compilerOptions": {
20
+ "noEmit": true,
21
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
22
+ "target": "ESNext",
23
+ "module": "ESNext",
24
+ "moduleResolution": "Bundler",
25
+ "lib": ["ESNext", "DOM"],
26
+ "types": ["node"],
27
+ "ignoreDeprecations": "6.0",
28
+ // 配置@别名
29
+ "baseUrl": ".",
30
+ "paths": {
31
+ "@/*": ["src/*"]
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "./tsconfig.app.json",
3
+ "include": ["src/**/__tests__/*", "env.d.ts"],
4
+ "exclude": [],
5
+ "compilerOptions": {
6
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
7
+
8
+ "lib": [],
9
+ "types": ["node", "jsdom"]
10
+ }
11
+ }
@@ -0,0 +1,33 @@
1
+ import { fileURLToPath, URL } from 'node:url'
2
+
3
+ import { defineConfig } from 'vite'
4
+ import vue from '@vitejs/plugin-vue'
5
+ import vueDevTools from 'vite-plugin-vue-devtools'
6
+ import tailwindcss from '@tailwindcss/vite'
7
+ import AutoImport from 'unplugin-auto-import/vite'
8
+ // import Components from 'unplugin-vue-components/vite'
9
+ // https://vite.dev/config/
10
+ export default defineConfig({
11
+ plugins: [
12
+ vue(),
13
+ vueDevTools(),
14
+ tailwindcss(),
15
+ AutoImport({
16
+ imports: ['vue'],
17
+ dts: 'src/auto-import.d.ts',
18
+
19
+ eslintrc: {
20
+ enabled: true, //生成eslint配置
21
+ filepath: './.eslintrc-auto-import.json', // 指定生成的 ESLint 配置文件路径
22
+ },
23
+ }),
24
+ // Components({
25
+ // dts: 'src/components.d.ts',
26
+ // }),
27
+ ],
28
+ resolve: {
29
+ alias: {
30
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
31
+ },
32
+ },
33
+ })
@@ -0,0 +1,14 @@
1
+ import { fileURLToPath } from 'node:url'
2
+ import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
3
+ import viteConfig from './vite.config'
4
+
5
+ export default mergeConfig(
6
+ viteConfig,
7
+ defineConfig({
8
+ test: {
9
+ environment: 'jsdom',
10
+ exclude: [...configDefaults.exclude, 'e2e/**'],
11
+ root: fileURLToPath(new URL('./', import.meta.url)),
12
+ },
13
+ }),
14
+ )
package/utils.js ADDED
@@ -0,0 +1,73 @@
1
+ import fs from "fs-extra";
2
+ import path from "path";
3
+ import chalk from "chalk";
4
+ import { fileURLToPath } from "url";
5
+ import { dirname } from "path";
6
+ import download from "download-git-repo";
7
+ import ora from "ora";
8
+
9
+ // 获取当前文件的完整路径(类似 CommonJS 中的 __filename)
10
+ const __filename = fileURLToPath(import.meta.url);
11
+
12
+ // 获取当前文件所在的目录(类似 CommonJS 中的 __dirname)
13
+ const __dirname = dirname(__filename);
14
+
15
+ // 模板目录路径(当前文件所在目录下的 template 文件夹)
16
+
17
+ const TEMPLATES_DIR = path.resolve(__dirname, "./template");
18
+ /**
19
+ * 读取template文件夹下的目录
20
+ */
21
+ async function getTemplateList() {
22
+ try {
23
+ if (!(await fs.pathExists(TEMPLATES_DIR))) {
24
+ console.log(chalk.red("读取模板列表失败"));
25
+ return [];
26
+ }
27
+ // 读取子目录
28
+ const templateList = await fs.readdir(TEMPLATES_DIR, {
29
+ // 返回目录
30
+ withFileTypes: true,
31
+ });
32
+ // 如果没有目录,返回空数组
33
+ if (templateList.length === 0) {
34
+ console.log(chalk.red("当前模板为空,请添加"));
35
+ return [];
36
+ }
37
+ // 过滤出目录
38
+ const dirs = templateList.filter((item) => item.isDirectory());
39
+ // 提取目录名
40
+ const templateNames = dirs.map((item) => {
41
+ // 名称和value都用文件名
42
+ const name = item.name;
43
+
44
+ return { name, value: name };
45
+ });
46
+ templateNames.push({
47
+ name: "自定义项目",
48
+ value: "custom",
49
+ });
50
+ return templateNames;
51
+ } catch (error) {
52
+ console.log(chalk.red("读取模板列表失败"));
53
+ // console.log(chalk.red(error.message));
54
+ return [];
55
+ }
56
+ }
57
+
58
+ async function downloadCustomTemplate(templatePath, projectPath) {
59
+ const spinner = ora("正在下载项目模板...").start(); //下载中
60
+ return new Promise((resolve, reject) => {
61
+ download(`direct:${templatePath}`, projectPath, { clone: true }, (err) => {
62
+ if (err) {
63
+ reject(err);
64
+ spinner.fail("项目模板下载失败"); //下载失败
65
+ } else {
66
+ resolve();
67
+ // console.log(chalk.green("项目模板下载成功"));
68
+ spinner.succeed("项目模板下载成功"); //下载成功
69
+ }
70
+ });
71
+ });
72
+ }
73
+ export { getTemplateList, downloadCustomTemplate };