feat: homepage

This commit is contained in:
MoYuan-CN
2025-11-17 19:25:36 +08:00
parent d16f70601b
commit ba9ee04387
31 changed files with 2567 additions and 1020 deletions

8
.editorconfig Normal file
View File

@@ -0,0 +1,8 @@
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
max_line_length = 100

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto eol=crlf

5
.gitignore vendored
View File

@@ -34,8 +34,3 @@ coverage
# Vitest # Vitest
__screenshots__/ __screenshots__/
# package
package-lock.json
pnpm-lock.yaml
yarn.lock

6
.prettierrc Normal file
View File

@@ -0,0 +1,6 @@
{
"tabWidth": 4,
"useTabs": false,
"vueIndentScriptAndStyle": true,
"bracketSameLine": true
}

View File

@@ -1,3 +1,7 @@
{ {
"recommendations": ["Vue.volar", "bradlc.vscode-tailwindcss"] "recommendations": [
"Vue.volar",
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig"
]
} }

View File

@@ -1,4 +1,4 @@
# EasyTierWeb # NeoUptime Web
This template should help get you started developing with Vue 3 in Vite. This template should help get you started developing with Vue 3 in Vite.
@@ -32,11 +32,17 @@ pnpm install
### Compile and Hot-Reload for Development ### Compile and Hot-Reload for Development
```sh ```sh
pnpm run dev pnpm dev
``` ```
### Type-Check, Compile and Minify for Production ### Type-Check, Compile and Minify for Production
```sh ```sh
pnpm run build pnpm build
```
### Lint with [ESLint](https://eslint.org/)
```sh
pnpm lint
``` ```

View File

@@ -1,14 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang=""> <html lang="">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico"> <link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="src/assets/style.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>EasyTierMC Uptime</title>
<title>Vite App</title> </head>
</head> <body class="bg-base-200 w-screen h-screen">
<body> <div id="app"></div>
<div id="app"></div> <script type="module" src="/src/main.ts"></script>
<script type="module" src="/src/main.ts"></script> </body>
</body>
</html> </html>

View File

@@ -1,38 +1,40 @@
{ {
"name": "neoeasytierweb", "name": "neouptime-web",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"packageManager": "pnpm@10.18.0", "engines": {
"engines": { "node": "^20.19.0 || >=22.12.0"
"node": "^20.19.0 || >=22.12.0" },
}, "scripts": {
"scripts": { "dev": "vite",
"dev": "vite", "build": "run-p type-check \"build-only {@}\" --",
"build": "run-p type-check \"build-only {@}\" --", "preview": "vite preview",
"preview": "vite preview", "build-only": "vite build",
"build-only": "vite build", "type-check": "vue-tsc --build",
"type-check": "vue-tsc --build" "lint": "eslint . --fix --cache"
}, },
"dependencies": { "dependencies": {
"echarts": "^6.0.0", "@iconify/tailwind4": "^1.1.0",
"neoeasytierweb": "link:", "@tailwindcss/vite": "^4.1.17",
"tailwindcss": "^4.1.17", "daisyui": "^5.5.4",
"vue": "^3.5.22", "pinia": "^3.0.4",
"vue-echarts": "^8.0.1", "tailwindcss": "^4.1.17",
"vue-router": "^4.6.3" "vue": "^3.5.24",
}, "vue-router": "^4.6.3"
"devDependencies": { },
"@tailwindcss/vite": "^4.1.17", "devDependencies": {
"@tsconfig/node22": "^22.0.2", "@iconify-json/octicon": "^1.2.19",
"@types/node": "^22.18.11", "@tsconfig/node22": "^22.0.3",
"@vitejs/plugin-vue": "^6.0.1", "@types/node": "^22.19.1",
"@vue/tsconfig": "^0.8.1", "@vitejs/plugin-vue": "^6.0.1",
"daisyui": "^5.4.7", "@vue/eslint-config-typescript": "^14.6.0",
"npm-run-all2": "^8.0.4", "@vue/tsconfig": "^0.8.1",
"typescript": "~5.9.0", "jiti": "^2.6.1",
"vite": "^7.1.11", "npm-run-all2": "^8.0.4",
"vite-plugin-vue-devtools": "^8.0.3", "typescript": "~5.9.3",
"vue-tsc": "^3.1.1" "vite": "npm:rolldown-vite@^7.2.5",
} "vite-plugin-vue-devtools": "^8.0.3",
"vue-tsc": "^3.1.3"
}
} }

2706
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,70 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router' import { Layout } from "./layout";
const year = new Date().getFullYear()
</script> </script>
<template> <template>
<div class="layout"> <Layout>
<header class="navbar bg-base-100 shadow-md"> <RouterView />
<div class="navbar-start"> </Layout>
<div class="dropdown">
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16" />
</svg>
</div>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
<li><RouterLink to="/">主页</RouterLink></li>
<li><RouterLink to="/monitor">节点监控</RouterLink></li>
<li><RouterLink to="/submit">提交节点</RouterLink></li>
</ul>
</div>
<div class="flex-1">
<h1 class="btn btn-ghost normal-case text-2xl font-bold">EasyTierMC Uptime</h1>
</div>
</div>
<div class="navbar-end hidden lg:flex">
<ul class="menu menu-horizontal px-1 gap-2">
<li><RouterLink to="/" class="btn btn-ghost">主页</RouterLink></li>
<li><RouterLink to="/monitor" class="btn btn-ghost">节点监控</RouterLink></li>
<li><RouterLink to="/submit" class="btn btn-ghost">提交节点</RouterLink></li>
</ul>
</div>
</header>
<main class="flex-1">
<RouterView />
</main>
<footer class="footer footer-center bg-base-200 text-base-content p-4 border-t">
<div>
<small>© {{ year }} EasyTierMC Uptime</small>
</div>
</footer>
</div>
</template> </template>
<style scoped> <style scoped></style>
.layout {
min-height: 100vh;
display: flex;
flex-direction: column;
}
header {
flex-shrink: 0;
}
main {
flex: 1;
padding: 1.25rem 1.5rem 2rem;
}
footer {
flex-shrink: 0;
}
@media (min-width: 1024px) {
main {
padding: 1.75rem 2rem 2.5rem;
}
}
</style>

View File

@@ -1,89 +0,0 @@
@import "tailwindcss";
@plugin "daisyui";
/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;
--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50;
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-indigo);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition:
color 0.5s,
background-color 0.5s;
line-height: 1.6;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

84
src/assets/index.css Normal file
View File

@@ -0,0 +1,84 @@
@import "tailwindcss";
@layer base {
*:not(.selectable) {
@apply select-none;
}
}
@plugin "@iconify/tailwind4";
@plugin "daisyui" {
themes: false;
excludes: "rootscrollgutter";
}
@plugin "daisyui/theme" {
name: "light";
default: true;
prefersdark: false;
color-scheme: "light";
--color-base-100: oklch(0.9782 0.0034 247.86);
--color-base-200: oklch(0.9782 0.0034 247.86);
--color-base-300: oklch(1 0 0);
--color-base-content: oklch(0.135 0.0111 254.04);
--color-primary: oklch(0.7967 0.1103 178.33);
--color-primary-content: oklch(0.0757 0.1103 178.33);
--color-secondary: oklch(0.7967 0.1103 62.49);
--color-secondary-content: oklch(0.0757 0.1103 62.49);
--color-accent: oklch(0.7967 0.1103 337.03);
--color-accent-content: oklch(0.0757 0.1103 337.03);
--color-neutral: oklch(14% 0.005 285.823);
--color-neutral-content: oklch(92% 0.004 286.32);
--color-info: oklch(0.701 0.201 255.48);
--color-info-content: oklch(25% 0.09 281.288);
--color-success: oklch(0.7701 0.1809 145.62);
--color-success-content: oklch(26% 0.051 172.552);
--color-warning: oklch(0.848 0.1394 72.63);
--color-warning-content: oklch(27% 0.077 45.635);
--color-error: oklch(0.7145 0.2234 26.79);
--color-error-content: oklch(25% 0.092 26.042);
--radius-selector: 0.5rem;
--radius-field: 0.25rem;
--radius-box: 0.5rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 1;
--noise: 0;
}
@plugin "daisyui/theme" {
name: "dark";
default: false;
prefersdark: true;
color-scheme: "dark";
--color-base-100: oklch(0.2735 0.0179 251.92);
--color-base-200: oklch(0.1763 0.014 258.36);
--color-base-300: oklch(0.1039 0.0194 248.35);
--color-base-content: oklch(0.9852 0 116.07);
--color-primary: oklch(0.7967 0.1103 178.33);
--color-primary-content: oklch(0.0757 0.1103 178.33);
--color-secondary: oklch(0.7967 0.1103 62.49);
--color-secondary-content: oklch(0.0757 0.1103 62.49);
--color-accent: oklch(0.7967 0.1103 337.03);
--color-accent-content: oklch(0.0757 0.1103 337.03);
--color-neutral: oklch(14% 0.005 285.823);
--color-neutral-content: oklch(92% 0.004 286.32);
--color-info: oklch(0.626 0.201 255.48);
--color-info-content: oklch(25% 0.09 281.288);
--color-success: oklch(0.6951 0.1809 145.62);
--color-success-content: oklch(26% 0.051 172.552);
--color-warning: oklch(0.773 0.1394 72.63);
--color-warning-content: oklch(27% 0.077 45.635);
--color-error: oklch(0.6395 0.2234 26.79);
--color-error-content: oklch(25% 0.092 26.042);
--radius-selector: 0.5rem;
--radius-field: 0.25rem;
--radius-box: 0.5rem;
--size-selector: 0.25rem;
--size-field: 0.25rem;
--border: 1px;
--depth: 1;
--noise: 0;
}

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 276 B

View File

@@ -1,29 +0,0 @@
@import './base.css';
#app {
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
padding: 3px;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
}
}
@media (min-width: 1024px) {
body {
}
#app {
padding: 0 2rem;
}
}

View File

@@ -1,92 +0,0 @@
<template>
<div>
<v-chart class="chart" :option="option" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import VChart from 'vue-echarts';
import china from "../../../public/china.json"
import * as echarts from 'echarts';
echarts.registerMap('china',china as any);
const data = [
{ name: '北京', value: 85 },
{ name: '上海', value: 92 },
{ name: '广东', value: 9 },
{ name: '浙江', value: 65 },
{ name: '江苏', value: 58 },
// 更多数据...
]
const option = ref<echarts.EChartsOption>({
tooltip: {
show: true,
formatter: '{b}: {c}个节点'
},
visualMap: {
type: 'piecewise',
min: 0,
max: 50,
pieces:[
{
max:5,
label:'少',
color:'#ff4d4d'
},
{
min:5,
max:15,
label:'中',
color:'#ffa64d'
},
{
min:15,
max:20,
label:'多',
color:'#ffcc00'
},
{
min:20,
max:30,
label:'非常多',
color:'#99cc33'
},
{
min:30,
label:'数据中心',
color:'#33cc33'
}
],
textStyle:{
color:'#fff'
}
},
series: [{
name: '服务器节点',
type: 'map',
map: 'china',
roam: false,
select: {
disabled: true // 禁用选择状态
},
emphasis: {
label: {
show: true,
},
itemStyle:{
areaColor:'#FFDE59'
}
},
data
}]
});
</script>
<style scoped>
.chart {
height: 600px;
width: 30%;
}
</style>

1
src/layout/Admin.vue Normal file
View File

@@ -0,0 +1 @@
<template></template>

20
src/layout/Default.vue Normal file
View File

@@ -0,0 +1,20 @@
<template>
<div class="layout">
<nav class="navbar bg-base-100 shadow-sm justify-between">
<a class="btn btn-ghost text-xl">EasyTierMC Uptime</a>
<section class="flex gap-2">
<button class="btn btn-link">Home</button>
<button class="btn btn-link">About</button>
<button class="btn btn-link">Docs</button>
</section>
<button class="btn btn-primary mr-4">Submit a Node</button>
</nav>
<div class="content p-4">
<slot />
</div>
<div class="divider"></div>
<footer class="p-4 -mt-2">
<p>&copy; {{ new Date().getFullYear() }} EasyTierMC. All Right Reserved.</p>
</footer>
</div>
</template>

1
src/layout/index.ts Normal file
View File

@@ -0,0 +1 @@
export { default as Layout } from "./index.vue";

26
src/layout/index.vue Normal file
View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
import { ref, watch, type Component } from "vue";
import { useRoute } from "vue-router";
import Default from "./Default.vue";
import Admin from "./Admin.vue";
const route = useRoute();
const LayoutComponent = ref<Component>(Default);
watch(
() => route.fullPath,
(newPath) => {
if (newPath === "/admin") {
LayoutComponent.value = Admin;
} else {
LayoutComponent.value = Default;
}
}
);
</script>
<template>
<LayoutComponent>
<slot />
</LayoutComponent>
</template>

View File

@@ -1,11 +1,14 @@
import './assets/main.css' import { createApp } from "vue";
import { createPinia } from "pinia";
import { createApp } from 'vue' import App from "./App.vue";
import App from './App.vue' import router from "./modules/router";
import router from './router'
const app = createApp(App) const app = createApp(App);
app.use(router) app.use(createPinia());
app.use(router);
app.mount('#app') app.mount("#app");
import "@/assets/index.css";

View File

@@ -0,0 +1,60 @@
import type { Component } from "vue";
import { createRouter, createWebHistory, type RouteRecordRaw } from "vue-router";
type ComponentImport = () => Promise<{ default: Component }>;
/**
* Step 1
* Lazy improt all files from \@/pages
* @returns ComponentImport
*/
const modules = import.meta.glob("../../pages/**/*.vue");
/**
* Step 2
* Convert file path to router path
* @param file - File path
* @returns Router path
*/
function pathFromFile(file: string): string {
let path = file.replace(/^\..\/..\/pages|\.vue$/g, "");
path = path.replace(/\[\.\.\.(.+?)\]/g, ":$1(.*)*"); // [...slug] → :slug(.*)*
path = path.replace(/\[(.+?)\]/g, ":$1"); // [id] → :id
path = path.replace(/\/index$/, "/"); // /user/index -> /user/
path = path.replace(/^\/index$/, "/"); // /index -> /
return path;
}
/**
* Step 3
* Create router routes from modules
* @returns RouteRecordRaw[]
*/
const routes: RouteRecordRaw[] = Object.keys(modules).map((file) => ({
path: pathFromFile(file),
component: modules[file] as ComponentImport,
}));
/**
* Step 4
* Auto regist 404 route (if /404.vue exists)
*/
const notFound = Object.keys(modules).find((f) => f.includes("/404.vue"));
if (notFound) {
routes.push({
path: "/:pathMatch(.*)*",
component: modules[notFound] as ComponentImport,
});
}
/**
* Step 5
* Create router instance
* @returns Router instance
*/
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;

96
src/pages/index.vue Normal file
View File

@@ -0,0 +1,96 @@
<script setup lang="ts">
import { ref } from "vue";
const nodes = ref([
{
id: 1,
status: "down",
name: "Beta Node 7",
location: "US",
sponsor: "Blue",
uptime: "99.8%",
},
{
id: 2,
status: "up",
name: "Alpha Node 3",
location: "UK",
sponsor: "Jason",
uptime: "98.5%",
},
{
id: 3,
status: "up",
name: "Gamma Node 2",
location: "JP",
sponsor: "Whatever Foundation",
uptime: "97.2%",
},
]);
</script>
<template>
<section class="pt-4 px-4">
<div>
<h1 class="text-3xl font-bold">Public Node Directory</h1>
<p class="opacity-50 mt-2">
Explore and contribute to our community-maintained list of public nodes. Your
<br />
participation ensures transparency and a robust network.
</p>
</div>
<div class="grid grid-cols-3 grid-rows-1 mt-4 w-full gap-4">
<div class="card shadow-[0_0_2px_0_var(--color-neutral-content)] p-4 bg-base-100">
<div class="stat-title">Total Nodes</div>
<div class="stat-value text-neutral-content">138</div>
<div class="stat-desc text-success">+1.2% this week</div>
</div>
<div class="card shadow-[0_0_2px_0_var(--color-neutral-content)] p-4 bg-base-100">
<div class="stat-title">Active Nodes</div>
<div class="stat-value text-neutral-content">72</div>
<div class="stat-desc text-success">+0.5% this week</div>
</div>
<div class="card shadow-[0_0_2px_0_var(--color-neutral-content)] p-4 bg-base-100">
<div class="stat-title">Total Sponsors</div>
<div class="stat-value text-neutral-content">24</div>
<div class="stat-desc text-success">+3.1% this week</div>
</div>
</div>
<div class="overflow-x-auto rounded-box border border-base-content/5 bg-base-100 mt-4">
<table class="table">
<!-- head -->
<thead class="bg-base-300">
<tr>
<th>STATUS</th>
<th>NODE NAME</th>
<th>LOCATION</th>
<th>SPONSOR</th>
<th>UPTIME</th>
<th>ACTIONS</th>
</tr>
</thead>
<tbody>
<tr v-for="node in nodes" :key="node.id">
<td>
<div class="inline-grid *:[grid-area:1/1] -translate-y-0.25" v-if="node.status === 'up'">
<div class="status status-success animate-ping"></div>
<div class="status status-success"></div>
</div>
<div class="status status-error -translate-y-0.25" v-else></div>
<span class="ml-2">{{ node.status == "up" ? "Online" : "Offline" }}</span>
</td>
<td>{{ node.name }}</td>
<td>{{ node.location }}</td>
<td>{{ node.sponsor }}</td>
<td>{{ node.uptime }}</td>
<td>
<button class="btn aspect-square">
<i class="icon-[octicon--info-24] size-5 -mx-2.5" />
</button>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</template>

View File

@@ -1,25 +0,0 @@
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView,
},
{
path: '/monitor',
name: 'monitor',
component: () => import('../views/MonitorView.vue'),
},
{
path: '/submit',
name: 'submit',
component: () => import('../views/SubmitView.vue'),
},
],
})
export default router

View File

@@ -1,15 +0,0 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
display: flex;
align-items: center;
}
}
</style>

View File

@@ -1,11 +0,0 @@
<template>
<section style="padding:2rem; text-align:center;">
<h2>欢迎来到 EasyTierMC Uptime</h2>
<p>使用上方导航查看节点监控或提交新的节点</p>
<Map />
</section>
</template>
<script setup lang="ts">
import Map from '@/components/dashboard/Map.vue';
</script>

View File

@@ -1,10 +0,0 @@
<template>
<div>
<h2>节点监控</h2>
<p>这里是节点监控页面</p>
</div>
</template>
<script setup lang="ts">
// 可根据需要添加逻辑
</script>

View File

@@ -1,10 +0,0 @@
<template>
<div>
<h2>提交节点</h2>
<p>这里是提交节点页面</p>
</div>
</template>
<script setup lang="ts">
// 可根据需要添加逻辑
</script>

View File

@@ -1,12 +1,12 @@
{ {
"extends": "@vue/tsconfig/tsconfig.dom.json", "extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"], "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"], "exclude": ["src/**/__tests__/*"],
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"]
}
} }
}
} }

View File

@@ -1,11 +1,11 @@
{ {
"files": [], "files": [],
"references": [ "references": [
{ {
"path": "./tsconfig.node.json" "path": "./tsconfig.node.json"
}, },
{ {
"path": "./tsconfig.app.json" "path": "./tsconfig.app.json"
} }
] ]
} }

View File

@@ -1,19 +1,19 @@
{ {
"extends": "@tsconfig/node22/tsconfig.json", "extends": "@tsconfig/node22/tsconfig.json",
"include": [ "include": [
"vite.config.*", "vite.config.*",
"vitest.config.*", "vitest.config.*",
"cypress.config.*", "cypress.config.*",
"nightwatch.conf.*", "nightwatch.conf.*",
"playwright.config.*", "playwright.config.*",
"eslint.config.*" "eslint.config.*"
], ],
"compilerOptions": { "compilerOptions": {
"noEmit": true, "noEmit": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"module": "ESNext", "module": "ESNext",
"moduleResolution": "Bundler", "moduleResolution": "Bundler",
"types": ["node"] "types": ["node"]
} }
} }

View File

@@ -1,20 +1,16 @@
import { fileURLToPath, URL } from 'node:url' import { fileURLToPath, URL } from "node:url";
import { defineConfig } from 'vite' import { defineConfig } from "vite";
import vue from '@vitejs/plugin-vue' import vue from "@vitejs/plugin-vue";
import vueDevTools from 'vite-plugin-vue-devtools' import vueDevTools from "vite-plugin-vue-devtools";
import tailwindcss from '@tailwindcss/vite' import tailwindcss from "@tailwindcss/vite";
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [vue(), vueDevTools(), tailwindcss()],
vue(), resolve: {
vueDevTools(), alias: {
tailwindcss() "@": fileURLToPath(new URL("./src", import.meta.url)),
], },
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}, },
}, });
})