01 · 架构与技术选型
个人站点通常有两类内容:
- 文档笔记 — 适合 Markdown,用 Starlight 自带 sidebar 组织
- 结构化导航 — 大量链接、分区、卡片分组,纯 MDX 维护成本高
书签模块解决的是第二类需求:按 Section → Card → Bookmark 三层组织链接,并提供搜索、分区 Tab、徽章等 UI。
同时希望:
- 线上是 静态站点(GitHub Pages / Vercel / Netlify)
- 本地有一个 可视化管理端,改完能 commit 进 Git
- 不引入独立后端数据库服务
文件夹src/bookmarks/
- README.md — 模块目录与数据流
文件夹shared/
- types.ts — Section / Card / Bookmark 领域类型
文件夹data/ — queries、page-data、serialize
- …
文件夹lib/ — 搜索、统计、Tab、favicon、badge
- …
文件夹components/ — BookmarkFavicon、BookmarkPageHeader、BookmarkSettingsIcon、StatsCards
- …
文件夹styles/ — bookmarks-theme-shared.css、bookmarks-card.css
- …
文件夹nav/
文件夹components/ — NavBookmarksPage、卡片与 Tab
- …
文件夹styles/ — bookmarks-page.css
- …
文件夹admin/
文件夹lib/ — 鉴权、API、拖拽 CRUD、api.server
- …
文件夹components/ — AdminApp、对话框、卡片网格
- …
文件夹styles/ — admin.css、bookmarks-app.css
- …
- nav/entry.astro — 导航 Astro 入口(injectRoute)→
/bookmarks/nav/ - admin/entry.astro — 管理端 Astro 入口(injectRoute)→
/bookmarks/admin/
文件夹db/
- data/bookmarks.ts — 唯一可提交数据源
- config.ts / seed.ts — Astro DB
- integrations/bookmarks-admin.ts — dev
/admin/api/*
文档站与书签模块 共用 @/theme 全站偏好(wwlight:color-* + init.inline.js),但书签页 不走 Starlight 布局——独立 Astro 页面挂载 React 根组件,导航页可全宽布局。
sequenceDiagram participant File as bookmarks.ts participant Seed as db/seed.ts participant DB as Astro DB participant Page as Astro 页面 participant React as React 岛屿 File->>Seed: 构建 / dev 启动 Seed->>DB: insert 三层表 Page->>DB: getBookmarkSections() Page->>React: JSON 写入 #bookmarks-sections-data React->>React: readBookmarkSectionsFromPage()
关键点: 运行时 React 不直接读 DB,而是读页面内嵌的 JSON。Astro 在 SSR/SSG 阶段查 DB,序列化后注入 DOM。这保证了:
- 导航页可以是
client:only="react",hydration 前已有数据 - 构建产物仍是静态 HTML + JS,无服务端运行时
管理端为何「本地可写、线上只读」
Section titled “管理端为何「本地可写、线上只读」”静态托管没有持久化磁盘。若在 production 开放 POST /admin/api/save,要么失败,要么需要额外后端。
当前方案:
| 环境 | 登录 | 编辑 UI | 保存到文件 |
|---|---|---|---|
astro dev | ✅ | ✅ | ✅ |
| 静态 build | ✅(门控) | ✅(UI 可见) | ❌ 403 仅开发环境可用 |
线上管理端页面主要用于 查看当前数据 或 导出;真正改数据在本地 vpr dev:admin → commit → push。
Astro 集成清单
Section titled “Astro 集成清单”astro.config.mjs 中与书签相关的集成:
integrations: [ db(), // Astro DB react(), // React 岛屿 bookmarksAdmin(), // 开发态 /admin/api/* 中间件 starlight({ /* … */ }),]bookmarksAdmin 是一个自定义 Astro Integration,在 astro:config:setup 里向 Vite 注册 middleware——只在 dev server 生效。
最小验证路径
Section titled “最小验证路径”-
克隆仓库并安装依赖
Terminal window vp i -
启动主站,访问书签页
/bookmarks/nav/ vpr dev -
启动管理端(首次会创建
.env并提示设密码)/bookmarks/admin/ vpr dev:admin -
在管理端改一条书签标题 → 保存 → 查看
db/data/bookmarks.ts是否更新 -
commit 该文件,push 后 CI 重新 build,线上书签页同步更新