feat: 初始化 Vue 前端工程与 embed 占位

This commit is contained in:
Nixevol
2026-09-30 05:50:37 +08:00
parent 5041a5bdd3
commit 857ba893fd
18 changed files with 1429 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
onlyBuiltDependencies[]=esbuild
+10
View File
@@ -0,0 +1,10 @@
package web
import "io/fs"
// Dist 返回嵌入的前端静态资源。
// 默认(无 embeddist 标签)为 stub 占位,保证裸 go build 可通过;
// task build 使用 -tags embeddist 嵌入 pnpm build 产物。
func Dist() fs.FS {
return distFS
}
+8
View File
@@ -0,0 +1,8 @@
//go:build embeddist
package web
import "embed"
//go:embed all:dist
var distFS embed.FS
+8
View File
@@ -0,0 +1,8 @@
//go:build !embeddist
package web
import "embed"
//go:embed all:stub
var distFS embed.FS
+7
View File
@@ -0,0 +1,7 @@
/// <reference types="vite/client" />
declare module "*.vue" {
import type { DefineComponent } from "vue";
const component: DefineComponent<Record<string, unknown>, Record<string, unknown>, unknown>;
export default component;
}
+12
View File
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>NixMsg</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
+29
View File
@@ -0,0 +1,29 @@
{
"name": "nixmsg-web",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview",
"typecheck": "vue-tsc -b --noEmit"
},
"dependencies": {
"naive-ui": "^2.43.1",
"pinia": "^3.0.3",
"vue": "^3.5.22",
"vue-router": "^4.5.1"
},
"devDependencies": {
"@types/node": "^26.6.3",
"@vitejs/plugin-vue": "^6.0.1",
"typescript": "~5.9.2",
"vite": "^7.1.7",
"vue-tsc": "^3.0.8"
},
"packageManager": "pnpm@10.17.1",
"pnpm": {
"onlyBuiltDependencies": ["esbuild"]
}
}
+1207
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -0,0 +1,14 @@
<script setup lang="ts">
import { NConfigProvider, NMessageProvider, NDialogProvider, zhCN, dateZhCN } from "naive-ui";
import { RouterView } from "vue-router";
</script>
<template>
<n-config-provider :locale="zhCN" :date-locale="dateZhCN" size="small">
<n-message-provider>
<n-dialog-provider>
<RouterView />
</n-dialog-provider>
</n-message-provider>
</n-config-provider>
</template>
+11
View File
@@ -0,0 +1,11 @@
import { createApp } from "vue";
import { createPinia } from "pinia";
import naive from "naive-ui";
import App from "./App.vue";
import { router } from "./router";
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.use(naive);
app.mount("#app");
+13
View File
@@ -0,0 +1,13 @@
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";
export const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/",
name: "home",
component: HomeView,
},
],
});
+7
View File
@@ -0,0 +1,7 @@
import { defineStore } from "pinia";
import { ref } from "vue";
export const useAppStore = defineStore("app", () => {
const title = ref("NixMsg");
return { title };
});
+15
View File
@@ -0,0 +1,15 @@
<script setup lang="ts">
import { NCard, NSpace, NText } from "naive-ui";
import { storeToRefs } from "pinia";
import { useAppStore } from "@/stores/app";
const { title } = storeToRefs(useAppStore());
</script>
<template>
<n-space vertical style="padding: 24px">
<n-card :title="title">
<n-text>管理后台骨架(T0.1)。后续页面由 W 线实现。</n-text>
</n-card>
</n-space>
</template>
+11
View File
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>NixMsg</title>
</head>
<body>
<p>前端尚未构建。请先执行 <code>task web:build</code> 再 <code>task build</code>。</p>
</body>
</html>
+27
View File
@@ -0,0 +1,27 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2022",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "preserve",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "env.d.ts"]
}
+7
View File
@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2023",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
+21
View File
@@ -0,0 +1,21 @@
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "node:path";
import { fileURLToPath } from "node:url";
const rootDir = path.dirname(fileURLToPath(import.meta.url));
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": path.resolve(rootDir, "src"),
},
},
server: {
proxy: {
"/api": "http://127.0.0.1:7443",
"/healthz": "http://127.0.0.1:7443",
},
},
});