docs(engineering): add project audit report and improvement plan
This commit introduces a comprehensive engineering audit report for the Tootaio Studio project. The report is structured into documents covering architecture, code quality, performance, security, CI/CD, and observability. It also includes a phased improvement roadmap and a set of `.patch` files to apply immediate fixes for content schemas, package scripts, and CI configuration.
This commit is contained in:
84
AGENTS.md
Normal file
84
AGENTS.md
Normal file
@@ -0,0 +1,84 @@
|
||||
当然可以,下面是完整的中文翻译版,保持了原文的结构与语气,适合直接放在项目的 `AGENTS.zh-CN.md` 中使用👇
|
||||
|
||||
---
|
||||
|
||||
# 仓库指南(Repository Guidelines)
|
||||
|
||||
本仓库托管了 **Tootaio Studio** 网站项目,基于 **Nuxt 4**、`@nuxt/content`、`@nuxt/ui` 和 i18n 构建。
|
||||
项目使用 **pnpm** 进行全部工作流程。
|
||||
|
||||
---
|
||||
|
||||
## 项目结构与模块组织
|
||||
|
||||
* `app/` — Nuxt 应用源码目录,包含:`pages/`、`layouts/`、`assets/`、`composables/`、`utils/` 等(例如:`app/pages/index.vue`)。
|
||||
* `content/` — 基于 YAML 的多语言内容文件(如:`content/en-US`、`content/zh-CN`)。内容结构定义在 `content.config.ts` 中。
|
||||
* `i18n/` — UI 翻译文件(JSON 格式),位于 `i18n/locales/<locale>/`。
|
||||
* `public/` — 静态资源目录,内容将原样提供给客户端。
|
||||
* 根级配置文件包括:`nuxt.config.ts`、`eslint.config.mjs`、`pnpm-workspace.yaml`。项目文档存放于 `docs/`。
|
||||
|
||||
---
|
||||
|
||||
## 构建、测试与开发命令
|
||||
|
||||
* **安装依赖**:`pnpm i`(会自动执行 `nuxt prepare`)
|
||||
* **开发服务器**:`pnpm dev` — 启动后访问 [http://localhost:3000](http://localhost:3000),支持 HMR。
|
||||
* **生产构建**:`pnpm build` — 生成 `.output/` 目录。
|
||||
* **预览构建**:`pnpm preview` — 以生产模式运行构建产物。
|
||||
* **静态生成**:`pnpm generate` — 执行 SSG(静态站点生成)。
|
||||
* **代码检查**:`pnpm exec eslint .`(手动执行时使用;CI 流程中会自动运行)。
|
||||
|
||||
---
|
||||
|
||||
## 代码风格与命名规范
|
||||
|
||||
* 使用 **TypeScript** 与 Vue 3 `<script setup lang="ts">`;配置文件采用 **ESM 模块** 格式。
|
||||
* 缩进统一为 **2 空格**;保持与现有代码库的引号与风格一致。
|
||||
* Vue 单文件组件(SFC)位于 `pages/` 下,文件名简洁(例如:`webDev.vue`);
|
||||
自定义组合式函数(composables)使用 **PascalCase**(如:`LocalizedCollection.ts`)。
|
||||
* ESLint 通过 `@nuxt/eslint` 配置,依赖编辑器集成与 CI/构建阶段反馈。
|
||||
* i18n 多语言 key 使用 **点号嵌套命名法**,例如:`$t('index.featuredProjects.viewDemo')`。
|
||||
|
||||
---
|
||||
|
||||
## 测试指南
|
||||
|
||||
* 当前尚未配置自动化测试。
|
||||
推荐在未来使用 **Vitest** 进行单元测试,**Playwright** 进行端到端(e2e)测试。
|
||||
* 在此之前,请进行本地验证:
|
||||
|
||||
* 运行 `pnpm dev`;
|
||||
* 切换多语言;
|
||||
* 检查 `content/*.yml` 是否符合 `content.config.ts` 中的 schema;
|
||||
* 确认 `pnpm build` 与 `pnpm preview` 能成功执行。
|
||||
|
||||
---
|
||||
|
||||
## 提交与 Pull Request 规范
|
||||
|
||||
* 遵循 **Conventional Commits** 规范,并带有 scope(可参考提交历史):
|
||||
|
||||
* 示例:`feat(content): …`、`refactor(ui): …`、`feat(pages): …`
|
||||
* 分支命名格式:
|
||||
|
||||
* `feat/<简短描述>`、`fix/<简短描述>`
|
||||
* Pull Request 要包含以下信息:
|
||||
|
||||
* **改动目的**
|
||||
* **关联的 Issue(如有)**
|
||||
* **UI 改动截图**
|
||||
* **测试步骤**
|
||||
* 若涉及内容文件,请确保 **中英文版本同步更新**。
|
||||
|
||||
---
|
||||
|
||||
## 内容与多语言(i18n)建议
|
||||
|
||||
* 在 `content/en-US/` 与 `content/zh-CN/` 下维护平行的内容文件。
|
||||
若新增页面类型,请同时扩展 `content.config.ts` 的 schema。
|
||||
* 使用 `useLocalizedCollection('index')` 或类似函数来获取内容,以获得类型支持与语言回退(fallback)。
|
||||
* 保持多语言翻译文件在各个 locale 目录下同步更新:`i18n/locales/<locale>/`。
|
||||
|
||||
---
|
||||
|
||||
是否希望我帮你把这份翻译排版成一个更正式、带 Front Matter 的文档版本(例如带 `title`, `lastUpdated`, `description` 的 YAML 头部),以便直接放进 Nuxt Content 或 docs 目录?
|
||||
28
docs/20251106/README.md
Normal file
28
docs/20251106/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Tootaio Studio 工程与架构审计(2025-11-06)
|
||||
|
||||
本报告对当前基于 Nuxt 4.2.0 的网站项目进行一次性全方位工程化审计,涵盖架构、代码质量、性能、CI/CD、安全与可观测性,并提供可直接落地的改进方案与补丁。
|
||||
|
||||
## 摘要
|
||||
- 架构总体清晰,采用 Nuxt Content + i18n + @nuxt/ui,模块职责明确(Low)。
|
||||
- 发现内容 Schema 与实际 YAML 不一致(Critical),导致构建期校验风险与类型漂移。
|
||||
- 缺少统一工程工具链(lint/typecheck/CI)(High)。
|
||||
- 未配置 Route Rules/SWR 与静态资源缓存(Medium)。
|
||||
- 运行时配置、监控与安全头未体系化(Medium)。
|
||||
|
||||
## 关键输出
|
||||
- 补丁:
|
||||
- 修正 `content.config.ts` Schema 与内容对齐(0001)。
|
||||
- 增加 `package.json` 脚本(lint/typecheck/check)(0002)。
|
||||
- 提供 GitHub Actions 工作流(lint → typecheck → build)(0003)。
|
||||
- 可选:为首页与静态资源增加 `routeRules`(0004)。
|
||||
- 提供 8 份专题文档:架构、质量、性能、CI/CD、安全、可观测性与路线图。
|
||||
|
||||
## 执行指引
|
||||
1) 审阅 `docs/20251106/` 文档;
|
||||
2) 依次应用补丁(位于 `docs/20251106/patches/`):
|
||||
- `git apply docs/20251106/patches/0001-content-config-align.patch`
|
||||
- `git apply docs/20251106/patches/0002-package-scripts.patch`
|
||||
- `git apply docs/20251106/patches/0003-github-actions-ci.patch`
|
||||
- (可选)`git apply docs/20251106/patches/0004-nuxt-route-rules.patch`
|
||||
3) 本地验证:`pnpm i && pnpm check && pnpm preview`。
|
||||
|
||||
52
docs/20251106/architecture.md
Normal file
52
docs/20251106/architecture.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# 架构结构与改进方案
|
||||
|
||||
本文审计 Nuxt 4.2.0 架构与模块使用,指出结构异味并提供可落地改进。
|
||||
|
||||
## 现状评估
|
||||
- 模块与目录(Low)
|
||||
- `app/`(pages/layouts/composables/utils/assets)职责清晰。
|
||||
- `content/` 与 `content.config.ts` 使用 zod 定义 Schema,利于类型驱动内容。
|
||||
- `i18n/` 采用 `locales/<locale>` 结构;`no_prefix` 策略与当前站点定位一致。
|
||||
- Nuxt 4 特性使用(Medium)
|
||||
- 自动导入:已使用(如 `useLocalizedCollection`)。建议将文件命名统一为 `useXxx.ts` 便于识别。
|
||||
- Runtime Config:未使用。建议引入 `runtimeConfig` 管理外部域名、监控 DSN 等。
|
||||
- Nitro Route Rules/缓存:未配置。建议为首页与静态资源设置 `prerender`+`swr` 与长缓存。
|
||||
- 设计风险(Critical)
|
||||
- `content.config.ts` 的 Index Schema 与 YAML 不一致:缺少 `title/description/seo` 字段;`icon/highlight/spotlight` 约束与内容不符。
|
||||
|
||||
## 改进策略
|
||||
1) 内容 Schema 对齐(Critical)
|
||||
- 为 Index 增加 `title/description/seo`;将 `icon` 设为可选,将 `highlight/spotlight` 设为可选并默认 `false`。
|
||||
- 参见补丁:`0001-content-config-align.patch`。
|
||||
2) 运行时配置(Medium)
|
||||
- 在 `nuxt.config.ts` 中:
|
||||
```ts
|
||||
export default defineNuxtConfig({
|
||||
runtimeConfig: {
|
||||
sentryDsn: '',
|
||||
public: { assetBase: 'https://img.tootaio.com' },
|
||||
},
|
||||
})
|
||||
```
|
||||
- 在代码中读取 `useRuntimeConfig()`,避免硬编码外链与密钥。
|
||||
3) 路由规则与缓存(Medium)
|
||||
- 为首页预渲染并设置 SWR,为构建产物设置 immutable 缓存:
|
||||
```ts
|
||||
export default defineNuxtConfig({
|
||||
routeRules: {
|
||||
'/': { prerender: true, swr: 3600 },
|
||||
'/_nuxt/**': {
|
||||
headers: { 'cache-control': 'public, max-age=31536000, immutable' },
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
- 参见补丁:`0004-nuxt-route-rules.patch`。
|
||||
4) 组合式命名与分层(Low)
|
||||
- 将 `app/composables/LocalizedCollection.ts` 重命名为 `useLocalizedCollection.ts`。
|
||||
- 保持 composable 只做“取数+组装”,复杂 UI/状态拆到组件/Pinia(若引入)。
|
||||
|
||||
## 与 Nuxt 4.2.0 兼容性
|
||||
- 现有 `compatibilityDate: '2025-07-15'` 符合要求。
|
||||
- 上述配置属于稳定 API:`routeRules/runtimeConfig/auto-import`,安全可用。
|
||||
|
||||
40
docs/20251106/ci-cd.md
Normal file
40
docs/20251106/ci-cd.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# CI/CD 设计与部署方案
|
||||
|
||||
## 目标
|
||||
提供从代码质量到产物构建的自动化流程:lint → typecheck → build。
|
||||
|
||||
## GitHub Actions(推荐)
|
||||
- 工作流文件参见补丁 `0003-github-actions-ci.patch`,关键步骤:
|
||||
- 使用 `actions/setup-node@v4` + `corepack enable`;
|
||||
- 安装依赖:`pnpm i --frozen-lockfile`;
|
||||
- 执行 `pnpm lint && pnpm typecheck && pnpm build`。
|
||||
|
||||
## 部署对比
|
||||
- Vercel(推荐)
|
||||
- 优点:零配置、内置 CDN、适配 Nuxt/Nitro;Preview 环境完善。
|
||||
- 缺点:免费额度受限;对长时间 SSR 任务需商用套餐。
|
||||
- Docker(自管)
|
||||
- 优点:环境一致性高;更灵活接入内网服务。
|
||||
- 缺点:需自建 CI/CD 与监控;维护成本更高。
|
||||
- 自建 Node + Nginx
|
||||
- 优点:成本可控;传统可见性强。
|
||||
- 缺点:手工配置多;需要额外缓存/CDN 配合。
|
||||
|
||||
## Dockerfile(示例)
|
||||
```dockerfile
|
||||
FROM node:20-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN corepack enable && pnpm i --frozen-lockfile && pnpm build
|
||||
|
||||
FROM node:20-alpine
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
COPY --from=build /app/.output ./.output
|
||||
EXPOSE 3000
|
||||
CMD ["node","./.output/server/index.mjs"]
|
||||
```
|
||||
|
||||
## 环境变量与密钥
|
||||
- 在 CI 中设置 `NITRO_PRESET`、`SENTRY_DSN` 等;Nuxt 通过 `runtimeConfig` 注入,避免硬编码。
|
||||
|
||||
41
docs/20251106/code-quality.md
Normal file
41
docs/20251106/code-quality.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# 代码规范与质量分析
|
||||
|
||||
## 主要发现
|
||||
- 类型定义(High)
|
||||
- `content.config.ts` 缺少 Index 页的 `title/description/seo`,导致 `page?.title` 等缺少类型提示;特定字段(`icon/highlight/spotlight`)与 YAML 不一致。
|
||||
- 组合式命名(Medium)
|
||||
- `LocalizedCollection.ts` 建议改为 `useLocalizedCollection.ts`,与 Nuxt 习惯保持一致,便于检索与自动导入心智统一。
|
||||
|
||||
## 统一约定
|
||||
- 文件与目录
|
||||
- composables:`useXxx.ts`(示例:`useLocalizedCollection.ts`)。
|
||||
- 页面:`pages/webDev.vue`(帕斯卡命名不用于路由页)。
|
||||
- 工具:`utils/some-helper.ts`,避免与 composables 混用。
|
||||
- 代码风格
|
||||
- TypeScript、ESM、Vue SFC `<script setup lang="ts">`。
|
||||
- 缩进 2 空格;组件/组合式函数采用明确的返回类型。
|
||||
- i18n 使用嵌套点式键:`$t('index.featuredProjects.viewDemo')`。
|
||||
- 提交规范
|
||||
- 参考历史:`feat(content): ...`、`refactor(ui): ...`、`feat(pages): ...`。
|
||||
- 分支:`feat/<desc>`、`fix/<desc>`。
|
||||
|
||||
## 重构建议(示例)
|
||||
1) 内容类型对齐(Critical)
|
||||
- 见补丁 `0001-content-config-align.patch`。
|
||||
2) 工程脚本完善(High)
|
||||
- 新增脚本:`lint/typecheck/check`,见补丁 `0002-package-scripts.patch`。
|
||||
3) 组合式命名(Medium)
|
||||
- 将 `LocalizedCollection.ts` 重命名为 `useLocalizedCollection.ts`(建议)。
|
||||
|
||||
## 示例:更严格的返回类型
|
||||
```ts
|
||||
export function useLocalizedCollection<B extends string>(baseName: B) {
|
||||
const { locale } = useI18n()
|
||||
type LocalizedKey = keyof { [K in keyof Collections as K extends `${B}_${string}` ? K : never]: any }
|
||||
type Schema = Collections[LocalizedKey]
|
||||
return useAsyncData<Schema | null>(`${baseName}-${locale.value}`, async () => {
|
||||
// ...
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
40
docs/20251106/observability.md
Normal file
40
docs/20251106/observability.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# 监控、日志与可观测性
|
||||
|
||||
## 目标
|
||||
构建可追踪错误、性能瓶颈与用户关键路径的最小监控闭环。
|
||||
|
||||
## Sentry(推荐)
|
||||
1) 配置 `runtimeConfig.sentryDsn`;
|
||||
2) 插件(示例,待引入依赖后启用):
|
||||
```ts
|
||||
// plugins/sentry.client.ts
|
||||
export default defineNuxtPlugin(() => {
|
||||
const { public: pub, sentryDsn } = useRuntimeConfig()
|
||||
if (!sentryDsn) return
|
||||
// @ts-ignore: add SDK in deps later
|
||||
const Sentry = (window as any).Sentry
|
||||
if (Sentry) {
|
||||
Sentry.init({ dsn: sentryDsn, tracesSampleRate: 0.1 })
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## 日志与错误边界
|
||||
- 服务器:使用 Nitro 默认日志(生产应接入集中式日志,如 CloudWatch/ELK)。
|
||||
- 客户端:全局错误捕获(`app:error` 事件)上报到 Sentry/自建网关。
|
||||
|
||||
## Web Vitals(可选)
|
||||
收集 LCP/CLS/INP 等指标(示例):
|
||||
```ts
|
||||
// plugins/web-vitals.client.ts
|
||||
import { onCLS, onINP, onLCP } from 'web-vitals'
|
||||
export default defineNuxtPlugin(() => {
|
||||
const send = (metric: any) => navigator.sendBeacon('/vitals', JSON.stringify(metric))
|
||||
onLCP(send); onCLS(send); onINP(send)
|
||||
})
|
||||
```
|
||||
|
||||
## Dashboard 路线
|
||||
- 第一步:仅错误计数与关键事务。
|
||||
- 第二步:接口慢查询、资源错误分布、版本追踪(commit SHA)。
|
||||
|
||||
89
docs/20251106/patches/0001-content-config-align.patch
Normal file
89
docs/20251106/patches/0001-content-config-align.patch
Normal file
@@ -0,0 +1,89 @@
|
||||
diff --git a/content.config.ts b/content.config.ts
|
||||
--- a/content.config.ts
|
||||
+++ b/content.config.ts
|
||||
@@
|
||||
const defineIndexSchema = () =>
|
||||
- z.object({
|
||||
- capabilities: z.object({
|
||||
- title: z.string(),
|
||||
- features: z.array(
|
||||
- z.object({
|
||||
- title: z.string(),
|
||||
- description: z.string(),
|
||||
- icon: z.string(),
|
||||
- })
|
||||
- ),
|
||||
- }),
|
||||
- featuredProjects: z.object({
|
||||
- title: z.string(),
|
||||
- projects: z.array(
|
||||
- z.object({
|
||||
- title: z.string(),
|
||||
- description: z.string(),
|
||||
- image: z.string(),
|
||||
- demoLink: z.string(),
|
||||
- highlight: z.boolean(),
|
||||
- spotlight: z.boolean(),
|
||||
- })
|
||||
- ),
|
||||
- }),
|
||||
- techStack: z.object({
|
||||
- title: z.string(),
|
||||
- }),
|
||||
- whyChooseUs: z.object({
|
||||
- title: z.string(),
|
||||
- features: z.array(
|
||||
- z.object({
|
||||
- title: z.string(),
|
||||
- description: z.string(),
|
||||
- icon: z.string(),
|
||||
- })
|
||||
- ),
|
||||
- }),
|
||||
- });
|
||||
+ z.object({
|
||||
+ title: z.string(),
|
||||
+ description: z.string(),
|
||||
+ seo: z
|
||||
+ .object({
|
||||
+ title: z.string().optional(),
|
||||
+ description: z.string().optional(),
|
||||
+ })
|
||||
+ .optional(),
|
||||
+ capabilities: z.object({
|
||||
+ title: z.string(),
|
||||
+ features: z.array(
|
||||
+ z.object({
|
||||
+ title: z.string(),
|
||||
+ description: z.string(),
|
||||
+ icon: z.string().optional(),
|
||||
+ })
|
||||
+ ),
|
||||
+ }),
|
||||
+ featuredProjects: z.object({
|
||||
+ title: z.string(),
|
||||
+ projects: z.array(
|
||||
+ z.object({
|
||||
+ title: z.string(),
|
||||
+ description: z.string(),
|
||||
+ image: z.string(),
|
||||
+ demoLink: z.string().url().optional(),
|
||||
+ highlight: z.boolean().optional().default(false),
|
||||
+ spotlight: z.boolean().optional().default(false),
|
||||
+ })
|
||||
+ ),
|
||||
+ }),
|
||||
+ techStack: z.object({
|
||||
+ title: z.string(),
|
||||
+ }),
|
||||
+ whyChooseUs: z.object({
|
||||
+ title: z.string(),
|
||||
+ features: z.array(
|
||||
+ z.object({
|
||||
+ title: z.string(),
|
||||
+ description: z.string(),
|
||||
+ icon: z.string().optional(),
|
||||
+ })
|
||||
+ ),
|
||||
+ }),
|
||||
+ });
|
||||
39
docs/20251106/patches/0002-package-scripts.patch
Normal file
39
docs/20251106/patches/0002-package-scripts.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
diff --git a/package.json b/package.json
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@
|
||||
"scripts": {
|
||||
- "build": "nuxt build",
|
||||
- "dev": "nuxt dev",
|
||||
- "generate": "nuxt generate",
|
||||
- "preview": "nuxt preview",
|
||||
- "postinstall": "nuxt prepare"
|
||||
+ "build": "nuxt build",
|
||||
+ "dev": "nuxt dev",
|
||||
+ "generate": "nuxt generate",
|
||||
+ "preview": "nuxt preview",
|
||||
+ "postinstall": "nuxt prepare",
|
||||
+ "typecheck": "nuxt typecheck",
|
||||
+ "lint": "eslint --ext .ts,.js,.mjs,.vue --ignore-path .gitignore .",
|
||||
+ "lint:fix": "pnpm lint -- --fix",
|
||||
+ "check": "pnpm lint && pnpm typecheck && pnpm build"
|
||||
},
|
||||
@@
|
||||
"dependencies": {
|
||||
"@iconify-json/mdi": "^1.2.3",
|
||||
"@nuxt/content": "3.8.0",
|
||||
"@nuxt/eslint": "1.10.0",
|
||||
"@nuxt/ui": "4.1.0",
|
||||
"@nuxtjs/i18n": "10.2.0",
|
||||
"@nuxtjs/seo": "3.2.2",
|
||||
"better-sqlite3": "^12.4.1",
|
||||
"eslint": "^9.39.0",
|
||||
"nuxt": "^4.2.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vue": "^3.5.22",
|
||||
"vue-router": "^4.6.3"
|
||||
- }
|
||||
+ },
|
||||
+ "engines": {
|
||||
+ "node": ">=18.20.0"
|
||||
+ }
|
||||
34
docs/20251106/patches/0003-github-actions-ci.patch
Normal file
34
docs/20251106/patches/0003-github-actions-ci.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/.github/workflows/ci.yml
|
||||
@@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
- name: Install dependencies
|
||||
run: pnpm i --frozen-lockfile
|
||||
- name: Lint
|
||||
run: pnpm lint
|
||||
- name: Typecheck
|
||||
run: pnpm typecheck
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
50
docs/20251106/patches/0004-nuxt-route-rules.patch
Normal file
50
docs/20251106/patches/0004-nuxt-route-rules.patch
Normal file
@@ -0,0 +1,50 @@
|
||||
diff --git a/nuxt.config.ts b/nuxt.config.ts
|
||||
--- a/nuxt.config.ts
|
||||
+++ b/nuxt.config.ts
|
||||
@@
|
||||
export default defineNuxtConfig({
|
||||
compatibilityDate: "2025-07-15",
|
||||
devtools: { enabled: true },
|
||||
modules: [
|
||||
"@nuxt/content",
|
||||
"@nuxt/ui",
|
||||
"@nuxt/eslint",
|
||||
"@nuxtjs/i18n",
|
||||
"@nuxtjs/seo",
|
||||
],
|
||||
css: ["@/assets/css/main.css"],
|
||||
app: {
|
||||
head: {
|
||||
titleTemplate: "%s - Tootaio Studio",
|
||||
meta: [
|
||||
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||
{ charset: "utf-8" },
|
||||
],
|
||||
},
|
||||
},
|
||||
@@
|
||||
seo: {
|
||||
meta: {
|
||||
title: DEFAULT_SEO.title,
|
||||
description: DEFAULT_SEO.description,
|
||||
keywords: DEFAULT_SEO.keywords,
|
||||
ogTitle: DEFAULT_SEO.title,
|
||||
ogDescription: DEFAULT_SEO.description,
|
||||
ogImage: DEFAULT_SEO.image,
|
||||
ogUrl: DEFAULT_SEO.url,
|
||||
twitterCard: "summary_large_image",
|
||||
twitterTitle: DEFAULT_SEO.title,
|
||||
twitterDescription: DEFAULT_SEO.description,
|
||||
twitterImage: DEFAULT_SEO.image,
|
||||
},
|
||||
},
|
||||
site: {
|
||||
url: "https://tootaio.com",
|
||||
},
|
||||
+ routeRules: {
|
||||
+ "/": { prerender: true, swr: 3600 },
|
||||
+ "/_nuxt/**": {
|
||||
+ headers: { "cache-control": "public, max-age=31536000, immutable" },
|
||||
+ },
|
||||
+ },
|
||||
});
|
||||
33
docs/20251106/performance.md
Normal file
33
docs/20251106/performance.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 性能诊断与优化建议
|
||||
|
||||
## 现状与影响
|
||||
- SSR/CSR(Medium):默认 SSR,未针对首页静态化或增量缓存配置,变化不频繁的内容可降本提速。
|
||||
- 资源缓存(Medium):未设置构建产物(`/_nuxt/**`)的长期缓存与 immutable,重复访问浪费带宽。
|
||||
- 图片与外链(Low):OG 图与背景图使用外部域名,建议统一通过 CDN 域名与缓存规则管理。
|
||||
|
||||
## Nuxt 4 定向优化
|
||||
1) Route Rules 与 SWR(Medium)
|
||||
- 预渲染首页并启用 SWR:降低首屏 TTFB。
|
||||
- 长缓存构建产物:
|
||||
```ts
|
||||
export default defineNuxtConfig({
|
||||
routeRules: {
|
||||
'/': { prerender: true, swr: 3600 },
|
||||
'/_nuxt/**': { headers: { 'cache-control': 'public, max-age=31536000, immutable' } },
|
||||
},
|
||||
})
|
||||
```
|
||||
- 参见补丁:`0004-nuxt-route-rules.patch`。
|
||||
2) 代码分割与懒加载(Low)
|
||||
- 仅在首屏需要时挂载大型组件(如轮播);通过 `v-if` 配合 `onMounted` 或 `client-only` 降低 SSR 负载。
|
||||
3) 构建与依赖(Low)
|
||||
- 保持 `pnpm-lock.yaml` 锁定;CI 使用 `pnpm i --frozen-lockfile` 保证可重复构建。
|
||||
4) 图片与静态资源(Medium)
|
||||
- 将站点图片统一迁到自有 CDN(如 Cloudflare/Vercel Assets),配置缓存与压缩。
|
||||
- 如未来引入 `@nuxt/image`,优先使用自动格式与尺寸。
|
||||
|
||||
## 部署建议
|
||||
- Node/Nitro(通用):适合 SSR + SWR 与渐进更新。
|
||||
- Edge(部份路由):静态资源 + 首页可下放至边缘,注意依赖兼容性。
|
||||
- Static/Generate:若大部分页面静态,可考虑 `pnpm generate` 并配合 CDN。
|
||||
|
||||
34
docs/20251106/roadmap.md
Normal file
34
docs/20251106/roadmap.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 分阶段工程化改进路线图
|
||||
|
||||
## 阶段一:基础规范化(1–2 天)
|
||||
- 目标:消除 Critical/High 风险,建立最小工程基线。
|
||||
- 动作:
|
||||
- 应用补丁 0001/0002;
|
||||
- 启用 `pnpm check` 在本地与 CI;
|
||||
- 修复内容与 Schema 校验。
|
||||
- 验证:`pnpm check` 全绿;手测多语言与内容渲染。
|
||||
|
||||
## 阶段二:模块解耦(2–3 天)
|
||||
- 目标:清晰分层,降低耦合与心智成本。
|
||||
- 动作:
|
||||
- 统一 composables 命名为 `useXxx.ts`;
|
||||
- 将硬编码外链迁到 `runtimeConfig.public.assetBase`;
|
||||
- 视需要引入 Pinia 拆分跨页状态。
|
||||
- 验证:路由与数据流稳定;影响面与回归点有测试用例(增量引入 Vitest)。
|
||||
|
||||
## 阶段三:自动化部署(1–2 天)
|
||||
- 目标:PR 即可验证、主干可随时发布。
|
||||
- 动作:
|
||||
- 应用补丁 0003(GitHub Actions);
|
||||
- 配置 Vercel/自建 Docker 部署;
|
||||
- 产出构建产物与环境变量清单。
|
||||
- 验证:PR 触发 CI,产物可预览。
|
||||
|
||||
## 阶段四:性能与监控(2–4 天)
|
||||
- 目标:稳定响应、端到端可观测。
|
||||
- 动作:
|
||||
- 应用补丁 0004(Route Rules/SWR);
|
||||
- 引入 Sentry(DSN + 插件);
|
||||
- 图片与静态资源走 CDN 与长缓存。
|
||||
- 验证:关键页面首屏数据、错误率与 Web Vitals。
|
||||
|
||||
33
docs/20251106/security.md
Normal file
33
docs/20251106/security.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 安全审计与防护建议
|
||||
|
||||
## 发现与等级
|
||||
- 外链与配置(Medium)
|
||||
- 外部图片/链接硬编码在源码中;建议迁移到 `runtimeConfig.public.assetBase` 并集中管理。
|
||||
- 内容与校验(High)
|
||||
- Content Schema 与数据不一致会在构建期暴露为错误或导致运行时空值处理不当。
|
||||
- 依赖与脚本(Low)
|
||||
- 缺少 `typecheck`/`lint` 脚本,易让问题晚发现。
|
||||
|
||||
## 防护清单
|
||||
1) 运行时配置(Medium)
|
||||
```ts
|
||||
export default defineNuxtConfig({
|
||||
runtimeConfig: {
|
||||
// 仅服务器可见
|
||||
sentryDsn: '',
|
||||
// 客户端可见
|
||||
public: {
|
||||
assetBase: 'https://img.tootaio.com',
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
2) 安全头(建议由网关/Nginx 配置)(Low)
|
||||
- `Content-Security-Policy`(允许必要的域名);
|
||||
- `X-Content-Type-Options: nosniff`、`Referrer-Policy: strict-origin-when-cross-origin`;
|
||||
- 静态资源 `Cache-Control: immutable`。
|
||||
3) 敏感信息检查(Medium)
|
||||
- 使用 `.gitignore` 与 CI 检查(如 `trufflehog`/`gitleaks`,后续可引入)。
|
||||
4) 依赖与锁定(Low)
|
||||
- 全量使用 `pnpm-lock.yaml`,CI 中启用 `--frozen-lockfile` 保证可复现构建。
|
||||
|
||||
147
docs/CODEX-PROMPT.md
Normal file
147
docs/CODEX-PROMPT.md
Normal file
@@ -0,0 +1,147 @@
|
||||
你现在是 **Tootaio Studio 项目的高级工程化顾问兼代码审计师**。
|
||||
你的职责是对这个基于 **Nuxt 4.2.0** 的项目进行一次**全方位工程级分析与优化规划**,
|
||||
以生成一份可以直接落地的**架构与工程化报告**。
|
||||
|
||||
---
|
||||
|
||||
## 一、项目背景
|
||||
|
||||
本仓库托管的是 **Tootaio Studio 网站**,基于以下技术栈:
|
||||
|
||||
* **Nuxt 4.2.0**
|
||||
* **@nuxt/content**(内容驱动)
|
||||
* **@nuxt/ui**
|
||||
* **i18n**
|
||||
* 包管理器:**pnpm**
|
||||
* 参考规范见 `AGENTS.md`(已提供)。
|
||||
|
||||
项目结构(符合最新 Nuxt 4.2.0):
|
||||
|
||||
```
|
||||
app/
|
||||
├─ assets/
|
||||
├─ composables/
|
||||
├─ layouts/
|
||||
├─ pages/
|
||||
├─ app.vue
|
||||
content/
|
||||
i18n/
|
||||
public/
|
||||
docs/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、分析目标
|
||||
|
||||
请你以拥有 10 年以上经验的 **Nuxt / 前端架构师** 的身份,
|
||||
对整个项目进行一次性全面分析与输出,目标包括但不限于:
|
||||
|
||||
1. **架构审计**
|
||||
|
||||
* 分析模块划分、Nuxt 4 特性使用(Nitro routes、auto-import、runtime config 等)。
|
||||
* 指出结构异味与潜在设计风险,并提供优化策略。
|
||||
* 判断 app/ 层结构是否遵循最新 Nuxt 4.2.0 官方建议。
|
||||
|
||||
2. **代码质量与维护性**
|
||||
|
||||
* 检查类型定义、composables 命名规范、逻辑分层是否清晰。
|
||||
* 判断是否存在可重构点(如 utils / composables / layouts 中重复逻辑)。
|
||||
* 给出统一命名与约定规范建议(含具体命名示例与代码片段)。
|
||||
|
||||
3. **性能与构建流程**
|
||||
|
||||
* 检查 SSR / CSR 渲染策略是否合理;有无未按需加载的模块。
|
||||
* 给出针对 Nuxt 4 的性能优化建议(build options, code-splitting, lazy loading, runtime config 优化等)。
|
||||
* 分析缓存策略、图片优化、CDN 使用、Nitro 部署模式(Node / Edge / Static)。
|
||||
|
||||
4. **开发体验与工程体系(DX)**
|
||||
|
||||
* 审查 eslint、prettier、tsconfig、vitest、commitlint、husky 等工具配置。
|
||||
* 给出一份推荐的现代化工程工具链(pnpm workspace + lint + test + CI/CD)配置清单。
|
||||
* 输出改进示例(配置文件、命令、package.json scripts)。
|
||||
|
||||
5. **CI/CD 与部署**
|
||||
|
||||
* 检查是否存在 GitHub Actions / CI 流程;如无,请生成完整示例:
|
||||
包含 lint → type-check → test → build → deploy 的 workflow 文件。
|
||||
* 同时给出 Vercel / Docker / 自建部署方案的对比说明。
|
||||
|
||||
6. **安全与可观测性**
|
||||
|
||||
* 检查敏感信息暴露、dotenv 安全、runtimeConfig 泄露风险。
|
||||
* 建议增加 Sentry/LogRocket/Datadog 等监控与日志方案,并提供示例代码。
|
||||
|
||||
7. **内容与多语言结构**
|
||||
|
||||
* 确认 `content/` 与 `i18n/` 结构是否合理、是否符合 `AGENTS.md` 规范。
|
||||
* 检查 YAML schema 与 JSON locale 对齐情况,建议自动化同步方案。
|
||||
|
||||
8. **改进路线图(Roadmap)**
|
||||
|
||||
* 生成一个可执行的工程化升级路线图:
|
||||
分为四个阶段(基础规范化 → 模块解耦 → 自动化部署 → 性能与监控)。
|
||||
* 每个阶段列出要点、执行命令和预期产出。
|
||||
|
||||
---
|
||||
|
||||
## 三、输出要求(一次性全部完成)
|
||||
|
||||
请将你的分析结果写入 `docs/20251106/` 目录中,包含以下文件(全部在本次回复中完整输出):
|
||||
|
||||
| 文件路径 | 内容说明 |
|
||||
| -------------------------------- | ---------------------------------------- |
|
||||
| `docs/20251106/README.md` | 分析概要与执行总结 |
|
||||
| `docs/20251106/architecture.md` | 架构结构与改进方案 |
|
||||
| `docs/20251106/code-quality.md` | 代码规范与质量分析 |
|
||||
| `docs/20251106/performance.md` | 性能诊断与优化建议 |
|
||||
| `docs/20251106/ci-cd.md` | CI/CD 设计与部署方案 |
|
||||
| `docs/20251106/security.md` | 安全审计与防护建议 |
|
||||
| `docs/20251106/observability.md` | 监控、日志与运行时可观测性 |
|
||||
| `docs/20251106/roadmap.md` | 分阶段工程化改进计划 |
|
||||
| `docs/20251106/patches/` | 含至少 3 个可应用的 `.patch` 文件(unified diff 格式) |
|
||||
|
||||
每个 patch 文件需附带:
|
||||
|
||||
* 修改目标与理由;
|
||||
* 应用命令(`git apply patches/xxx.patch`);
|
||||
* 改动前后对比(`--- a/... +++ b/...`);
|
||||
* 若涉及配置文件,请保持类型安全与 Nuxt 4.2.0 兼容。
|
||||
|
||||
---
|
||||
|
||||
## 四、格式要求
|
||||
|
||||
* 所有输出以 Markdown 格式展示;
|
||||
* 按文件分节,使用代码块展示 `.patch` 内容;
|
||||
* 每份文档前加上清晰标题与简短摘要;
|
||||
* 禁止模糊性推迟或要求我继续上传文件;
|
||||
* 如果无法直接读取仓库,请列出你需要的关键文件清单(按优先级),但仍需生成基于假设的分析报告与目录结构模板。
|
||||
|
||||
---
|
||||
|
||||
## 五、风格与深度要求
|
||||
|
||||
* 用语风格:专业、实操、能落地;
|
||||
* 所有建议应附示例代码、命令、配置;
|
||||
* 明确指出每个问题的严重程度(Critical / High / Medium / Low);
|
||||
* 推荐方案必须与 Nuxt 4.2.0 当前版本特性兼容;
|
||||
* 输出中请表现出架构师的思考过程(但不需解释 Prompt)。
|
||||
|
||||
---
|
||||
|
||||
## 六、触发执行
|
||||
|
||||
准备好后,请开始分析项目并输出完整报告。
|
||||
触发关键词:
|
||||
|
||||
`ANALYZE_AND_OUTPUT_NOW`
|
||||
|
||||
---
|
||||
|
||||
## 🔚 Prompt 结束
|
||||
|
||||
---
|
||||
|
||||
是否希望我现在帮你生成这个 Prompt 的 **可直接存放在仓库根目录的 `codex_prompt.md` 版本**(带标题、描述和 front-matter)?
|
||||
那样你只需放进仓库、Codex 扫描就能自动理解执行。
|
||||
Reference in New Issue
Block a user