@roki-h5/create-roki-app 0.1.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.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +67 -0
- package/package.json +41 -0
- package/templates/h5/.env.development +1 -0
- package/templates/h5/index.html +19 -0
- package/templates/h5/package.json +27 -0
- package/templates/h5/postcss.config.js +17 -0
- package/templates/h5/src/App.vue +3 -0
- package/templates/h5/src/api/index.ts +9 -0
- package/templates/h5/src/api/request.ts +78 -0
- package/templates/h5/src/assets/images/top-bg.png +0 -0
- package/templates/h5/src/assets/styles/main.css +21 -0
- package/templates/h5/src/main.ts +16 -0
- package/templates/h5/src/router/index.ts +24 -0
- package/templates/h5/src/stores/index.ts +15 -0
- package/templates/h5/src/utils/debounce.ts +20 -0
- package/templates/h5/src/utils/rem.ts +37 -0
- package/templates/h5/src/views/home/index.vue +60 -0
- package/templates/h5/src/vite-env.d.ts +9 -0
- package/templates/h5/tsconfig.json +20 -0
- package/templates/h5/vite.config.ts +19 -0
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { cyan, green, red } from "kolorist";
|
|
8
|
+
import prompts from "prompts";
|
|
9
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
var TEMPLATE_DIR = path.resolve(__dirname, "../templates/h5");
|
|
11
|
+
async function main() {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
let projectName = args[0];
|
|
14
|
+
if (!projectName) {
|
|
15
|
+
const result = await prompts({
|
|
16
|
+
type: "text",
|
|
17
|
+
name: "name",
|
|
18
|
+
message: "\u9879\u76EE\u540D\u79F0",
|
|
19
|
+
initial: "roki-h5",
|
|
20
|
+
validate: (value) => value.trim() ? true : "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"
|
|
21
|
+
});
|
|
22
|
+
if (!result.name) {
|
|
23
|
+
console.log(red("\u5DF2\u53D6\u6D88"));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
projectName = result.name.trim();
|
|
27
|
+
}
|
|
28
|
+
const targetDir = path.resolve(process.cwd(), projectName);
|
|
29
|
+
if (fs.existsSync(targetDir)) {
|
|
30
|
+
console.log(red(`\u76EE\u5F55 ${projectName} \u5DF2\u5B58\u5728`));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
copyDir(TEMPLATE_DIR, targetDir, projectName);
|
|
34
|
+
console.log();
|
|
35
|
+
console.log(green(`\u2713 \u9879\u76EE ${projectName} \u521B\u5EFA\u6210\u529F`));
|
|
36
|
+
console.log();
|
|
37
|
+
console.log(` cd ${projectName}`);
|
|
38
|
+
console.log(" pnpm install");
|
|
39
|
+
console.log(" pnpm dev");
|
|
40
|
+
console.log();
|
|
41
|
+
}
|
|
42
|
+
function copyDir(src, dest, projectName) {
|
|
43
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
44
|
+
for (const file of fs.readdirSync(src)) {
|
|
45
|
+
const srcPath = path.join(src, file);
|
|
46
|
+
const destPath = path.join(dest, file);
|
|
47
|
+
if (fs.statSync(srcPath).isDirectory()) {
|
|
48
|
+
copyDir(srcPath, destPath, projectName);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (isBinaryAsset(file)) {
|
|
52
|
+
fs.copyFileSync(srcPath, destPath);
|
|
53
|
+
} else {
|
|
54
|
+
let content = fs.readFileSync(srcPath, "utf-8");
|
|
55
|
+
content = content.replace(/__PROJECT_NAME__/g, projectName);
|
|
56
|
+
fs.writeFileSync(destPath, content);
|
|
57
|
+
}
|
|
58
|
+
console.log(cyan(` + ${path.relative(process.cwd(), destPath)}`));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function isBinaryAsset(filename) {
|
|
62
|
+
return /\.(png|jpe?g|gif|webp|ico|woff2?|ttf|eot)$/i.test(filename);
|
|
63
|
+
}
|
|
64
|
+
main().catch((err) => {
|
|
65
|
+
console.error(red(String(err)));
|
|
66
|
+
process.exit(1);
|
|
67
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@roki-h5/create-roki-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Roki H5 项目脚手架",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "http://172.18.10.96/260613/roki-ui.git",
|
|
10
|
+
"directory": "packages/create-roki"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"create-roki-app": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"templates"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public",
|
|
24
|
+
"registry": "https://registry.npmjs.org/"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"kolorist": "^1.8.0",
|
|
28
|
+
"prompts": "^2.4.2"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^22.10.2",
|
|
32
|
+
"@types/prompts": "^2.4.9",
|
|
33
|
+
"tsup": "^8.3.5",
|
|
34
|
+
"typescript": "^5.7.2"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup",
|
|
38
|
+
"dev": "tsup --watch",
|
|
39
|
+
"typecheck": "tsc --noEmit"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_BASE_API=
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<!-- viewport-fit=cover 必须,否则 iOS 刘海屏 safe-area-inset-top 为 0 -->
|
|
6
|
+
<meta
|
|
7
|
+
name="viewport"
|
|
8
|
+
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover"
|
|
9
|
+
/>
|
|
10
|
+
<meta name="mobile-web-app-capable" content="yes" />
|
|
11
|
+
<meta name="format-detection" content="telephone=no" />
|
|
12
|
+
<meta name="apple-touch-fullscreen" content="yes" />
|
|
13
|
+
<title>__PROJECT_NAME__</title>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<div id="app" class="roki-reset"></div>
|
|
17
|
+
<script type="module" src="/src/main.ts"></script>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PROJECT_NAME__",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vue-tsc -b && vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@roki-h5/ui": "^0.1.0",
|
|
13
|
+
"axios": "^1.7.9",
|
|
14
|
+
"pinia": "^2.3.0",
|
|
15
|
+
"vue": "^3.5.13",
|
|
16
|
+
"vue-router": "^4.5.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
20
|
+
"autoprefixer": "^10.4.20",
|
|
21
|
+
"postcss": "^8.4.49",
|
|
22
|
+
"postcss-pxtorem": "^6.1.0",
|
|
23
|
+
"typescript": "^5.7.2",
|
|
24
|
+
"vite": "^6.0.3",
|
|
25
|
+
"vue-tsc": "^2.1.10"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import autoprefixer from 'autoprefixer'
|
|
2
|
+
import postcssPxtorem from 'postcss-pxtorem'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
plugins: [
|
|
6
|
+
autoprefixer(),
|
|
7
|
+
postcssPxtorem({
|
|
8
|
+
rootValue: 37.5,
|
|
9
|
+
unitPrecision: 6,
|
|
10
|
+
propList: ['*'],
|
|
11
|
+
selectorBlackList: ['#app', '.ignore-vw'],
|
|
12
|
+
replace: true,
|
|
13
|
+
mediaQuery: false,
|
|
14
|
+
minPixelValue: 1,
|
|
15
|
+
}),
|
|
16
|
+
],
|
|
17
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import axios, { type AxiosRequestConfig } from 'axios'
|
|
2
|
+
import { useAppStore } from '@/stores'
|
|
3
|
+
|
|
4
|
+
function isRequestTimeout(error: unknown) {
|
|
5
|
+
if (!error || typeof error !== 'object') return false
|
|
6
|
+
const err = error as {
|
|
7
|
+
code?: string
|
|
8
|
+
message?: string
|
|
9
|
+
name?: string
|
|
10
|
+
}
|
|
11
|
+
return (
|
|
12
|
+
err.code === 'ECONNABORTED' ||
|
|
13
|
+
err.code === 'ETIMEDOUT' ||
|
|
14
|
+
(typeof err.message === 'string' &&
|
|
15
|
+
(err.message.toLowerCase().includes('timeout') ||
|
|
16
|
+
err.message.toLowerCase().includes('timed out'))) ||
|
|
17
|
+
err.name === 'TimeoutError'
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function showError(message: string) {
|
|
22
|
+
console.warn('[API]', message)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 业务请求封装,成功条件:rc === 0 或 success === true */
|
|
26
|
+
export function devReq<T = unknown>(config: AxiosRequestConfig) {
|
|
27
|
+
return new Promise<T>((resolve, reject) => {
|
|
28
|
+
const appStore = useAppStore()
|
|
29
|
+
const instance = axios.create({
|
|
30
|
+
headers: {
|
|
31
|
+
'Content-Type': 'application/json;charset=UTF-8',
|
|
32
|
+
'app-id': 'roki_app_h5',
|
|
33
|
+
Authorization: `Bearer ${appStore.accessToken}`,
|
|
34
|
+
},
|
|
35
|
+
timeout: 10000,
|
|
36
|
+
baseURL: config.baseURL || import.meta.env.VITE_BASE_API,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
instance(config)
|
|
40
|
+
.then((res) => {
|
|
41
|
+
const data = res.data as {
|
|
42
|
+
rc?: number
|
|
43
|
+
success?: boolean
|
|
44
|
+
msg?: string
|
|
45
|
+
message?: string
|
|
46
|
+
error_description?: string
|
|
47
|
+
error?: string
|
|
48
|
+
}
|
|
49
|
+
const ok = data.rc === 0 || data.success
|
|
50
|
+
if (ok) {
|
|
51
|
+
resolve(res.data as T)
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
const errMsg =
|
|
55
|
+
data.msg ||
|
|
56
|
+
data.message ||
|
|
57
|
+
data.error_description ||
|
|
58
|
+
data.error ||
|
|
59
|
+
'请求失败'
|
|
60
|
+
showError(errMsg)
|
|
61
|
+
reject(errMsg)
|
|
62
|
+
})
|
|
63
|
+
.catch((err) => {
|
|
64
|
+
if (err.response?.status === 0) {
|
|
65
|
+
reject(err)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
if (isRequestTimeout(err)) {
|
|
69
|
+
showError('请求超时,请检查网络状态')
|
|
70
|
+
reject(err)
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
const desc = err.response?.data?.error_description
|
|
74
|
+
showError(desc || '请求异常')
|
|
75
|
+
reject(err)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
html,
|
|
2
|
+
body {
|
|
3
|
+
margin: 0;
|
|
4
|
+
padding: 0;
|
|
5
|
+
background: #f5f6f8;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
#app {
|
|
9
|
+
min-height: 100vh;
|
|
10
|
+
min-height: 100dvh;
|
|
11
|
+
position: relative;
|
|
12
|
+
isolation: isolate;
|
|
13
|
+
background:
|
|
14
|
+
url('../images/top-bg.png') no-repeat top center / 100% 800px,
|
|
15
|
+
#f0f2f5;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.page {
|
|
19
|
+
min-height: 100vh;
|
|
20
|
+
min-height: 100dvh;
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createApp } from 'vue'
|
|
2
|
+
import { createPinia } from 'pinia'
|
|
3
|
+
import RokiUI from '@roki-h5/ui'
|
|
4
|
+
import '@roki-h5/ui/style.css'
|
|
5
|
+
import { setupRem } from '@/utils/rem'
|
|
6
|
+
import router from '@/router'
|
|
7
|
+
import App from './App.vue'
|
|
8
|
+
import '@/assets/styles/main.css'
|
|
9
|
+
|
|
10
|
+
setupRem()
|
|
11
|
+
|
|
12
|
+
const app = createApp(App)
|
|
13
|
+
app.use(createPinia())
|
|
14
|
+
app.use(router)
|
|
15
|
+
app.use(RokiUI)
|
|
16
|
+
app.mount('#app')
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRouter, createWebHashHistory } from 'vue-router'
|
|
2
|
+
import Home from '@/views/home/index.vue'
|
|
3
|
+
|
|
4
|
+
const router = createRouter({
|
|
5
|
+
history: createWebHashHistory(import.meta.env.BASE_URL),
|
|
6
|
+
routes: [
|
|
7
|
+
{
|
|
8
|
+
path: '/',
|
|
9
|
+
name: 'Home',
|
|
10
|
+
component: Home,
|
|
11
|
+
meta: { title: '__PROJECT_NAME__' },
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
scrollBehavior: () => ({ top: 0 }),
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
router.afterEach((to) => {
|
|
18
|
+
const title = to.meta?.title
|
|
19
|
+
if (title != null && title !== '') {
|
|
20
|
+
document.title = String(title)
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
export default router
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
import { defineStore } from 'pinia'
|
|
3
|
+
|
|
4
|
+
export const useAppStore = defineStore('app', () => {
|
|
5
|
+
const accessToken = ref('')
|
|
6
|
+
|
|
7
|
+
function setAccessToken(token: string) {
|
|
8
|
+
accessToken.value = token
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
accessToken,
|
|
13
|
+
setAccessToken,
|
|
14
|
+
}
|
|
15
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function debounce<T extends (...args: unknown[]) => unknown>(
|
|
2
|
+
fn: T,
|
|
3
|
+
wait: number,
|
|
4
|
+
options: { leading?: boolean; trailing?: boolean } = {},
|
|
5
|
+
) {
|
|
6
|
+
const { leading = false, trailing = true } = options
|
|
7
|
+
let timer: ReturnType<typeof setTimeout> | null = null
|
|
8
|
+
|
|
9
|
+
return function debounced(this: unknown, ...args: Parameters<T>) {
|
|
10
|
+
const invoke = () => {
|
|
11
|
+
timer = null
|
|
12
|
+
if (trailing) fn.apply(this, args)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const callNow = leading && !timer
|
|
16
|
+
if (timer) clearTimeout(timer)
|
|
17
|
+
timer = setTimeout(invoke, wait)
|
|
18
|
+
if (callNow) fn.apply(this, args)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** 375 设计稿 rem 自适应 */
|
|
2
|
+
export function setupRem() {
|
|
3
|
+
const baseSize = 37.5
|
|
4
|
+
const designWidth = 375
|
|
5
|
+
let lastWidth = window.innerWidth
|
|
6
|
+
let timer: ReturnType<typeof setTimeout> | null = null
|
|
7
|
+
|
|
8
|
+
function setRem() {
|
|
9
|
+
const isLandscape = window.innerWidth > window.innerHeight
|
|
10
|
+
const baseWidth = isLandscape ? window.innerHeight : window.innerWidth
|
|
11
|
+
const maxWidth = 375
|
|
12
|
+
const limitedWidth = Math.min(baseWidth, maxWidth)
|
|
13
|
+
const scale = limitedWidth / designWidth
|
|
14
|
+
const fontSize = baseSize * Math.min(scale, 2)
|
|
15
|
+
document.documentElement.style.fontSize = `${fontSize}px`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function debounceSetRem() {
|
|
19
|
+
if (timer) clearTimeout(timer)
|
|
20
|
+
timer = setTimeout(setRem, 100)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setRem()
|
|
24
|
+
|
|
25
|
+
window.addEventListener('resize', () => {
|
|
26
|
+
if (lastWidth !== window.innerWidth) {
|
|
27
|
+
lastWidth = window.innerWidth
|
|
28
|
+
debounceSetRem()
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
window.addEventListener('orientationchange', debounceSetRem)
|
|
33
|
+
|
|
34
|
+
window.addEventListener('pageshow', (event) => {
|
|
35
|
+
if (event.persisted) setRem()
|
|
36
|
+
})
|
|
37
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
function onBack() {
|
|
3
|
+
history.back()
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function onMore() {
|
|
7
|
+
console.log('more')
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<div class="page home-page">
|
|
13
|
+
<RokiNavBar title="__PROJECT_NAME__" @click-left="onBack">
|
|
14
|
+
<template #right>
|
|
15
|
+
<span
|
|
16
|
+
role="button"
|
|
17
|
+
tabindex="0"
|
|
18
|
+
class="home-page__more"
|
|
19
|
+
aria-label="更多"
|
|
20
|
+
@click.stop="onMore"
|
|
21
|
+
>
|
|
22
|
+
⋯
|
|
23
|
+
</span>
|
|
24
|
+
</template>
|
|
25
|
+
</RokiNavBar>
|
|
26
|
+
|
|
27
|
+
<main class="home-page__content">
|
|
28
|
+
<p class="home-page__tip">向下滚动,导航栏背景会从透明渐变为白色。</p>
|
|
29
|
+
<div class="home-page__spacer" />
|
|
30
|
+
</main>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<style scoped>
|
|
35
|
+
.home-page__content {
|
|
36
|
+
padding: 24px 18px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.home-page__tip {
|
|
40
|
+
margin: 0;
|
|
41
|
+
font-size: 14px;
|
|
42
|
+
color: rgba(0, 0, 0, 0.6);
|
|
43
|
+
line-height: 1.6;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.home-page__more {
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
width: 42px;
|
|
51
|
+
height: 42px;
|
|
52
|
+
font-size: 20px;
|
|
53
|
+
line-height: 1;
|
|
54
|
+
color: rgba(0, 0, 0, 0.85);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.home-page__spacer {
|
|
58
|
+
height: 120vh;
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"jsx": "preserve",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"isolatedModules": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"baseUrl": ".",
|
|
15
|
+
"paths": {
|
|
16
|
+
"@/*": ["src/*"]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"include": ["src/**/*.ts", "src/**/*.vue"]
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { defineConfig } from 'vite'
|
|
4
|
+
import vue from '@vitejs/plugin-vue'
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
7
|
+
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
plugins: [vue()],
|
|
10
|
+
resolve: {
|
|
11
|
+
alias: {
|
|
12
|
+
'@': path.resolve(__dirname, 'src'),
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
server: {
|
|
16
|
+
host: true,
|
|
17
|
+
port: 5173,
|
|
18
|
+
},
|
|
19
|
+
})
|