Skip to content

背景与目标

  • 用 VitePress 快速搭建个人学习空间「橘子学习天地」。
  • 需求:中文化文案、首页引导、笔记聚合、分类与归档、学习计划、基础鉴权、细腻动效、可在边缘静态平台一键部署。

总体方案

  • 框架:VitePress 1.6.x + 默认主题扩展。
  • 内容组织:
    • 学习笔记:pages/notes/**,由页面运行时通过 import.meta.glob 聚合,自动生成列表(见「学习笔记」页)。
    • 分类:从笔记的 categories/category 前言区聚合得到(见「分类」页)。
    • 归档:按笔记的 date 计算 YYYY-MM 分组(见「归档」页)。
    • 学习计划:在 pages/plan/entries/** 的 Frontmatter 中以数组维护计划条目,由页面运行时聚合(见「学习计划」页)。
  • 导航与主题:在 .vitepress/config.mts 中统一配置;动效与样式在 .vitepress/theme/style.css;导航切换淡入在 .vitepress/theme/index.ts

鉴权设计(前端门禁)

  • 目标:进入首页之外的页面前进行校验;成功后记住状态;支持子路径部署。
  • 元数据文件:pages/public/auth.json
    • 采用 PBKDF2-SHA256(含随机盐与迭代次数),避免明文或简单哈希。
    • 读取路径使用 withBase('/auth.json'),兼容 base 子路径。
  • 校验逻辑:.vitepress/theme/components/AuthGate.vue
    • 使用 WebCrypto subtle 计算 PBKDF2;失败 5 次后锁定 5 分钟;通过后写入 localStorage 标记。
    • 未通过时为 body 添加 vp-auth-locked 类,隐藏主内容,仅显示认证弹窗。
  • 旋转秘钥:
    1. 在本地用 Node 生成新 JSON:
    bash
    node -e "const c=require('crypto');const s=process.argv[1];const salt=c.randomBytes(16).toString('hex');const it=100000;const hash=c.pbkdf2Sync(s,salt,it,32,'sha256').toString('hex');console.log(JSON.stringify({algo:'pbkdf2-sha256',iterations:it,salt,hash},null,2))" 你的秘钥
    1. 覆盖 pages/public/auth.json,并清理浏览器 localStorage 中的 vp_auth_ok
  • 说明:这是前端静态门禁,适合作为“基础拦截/引导”。强安全建议在边缘/服务端再加访问控制。

内容模型与前言区约定

  1. 学习笔记(自动聚合)
md
---
title: JavaScript 闭包笔记
date: 2025-11-01
categories: [JavaScript]
tags: [闭包, 函数]
description: 闭包原理与常见误区整理
---

正文……
  1. 学习计划(从 Markdown 读取,不用浏览器本地存储)

文件放在 pages/plan/entries/ 下:

md
---
title: 2025 Q1 学习计划
date: 2025-01-01
plans:
  - title: 学习 TypeScript 深入
    due: 2025-02-10
    status: doing
  - title: 阅读《计算机网络》
    due: 2025-03-01
    status: todo
  - title: 完成一个 VitePress 主题
    status: done
---

说明……

动效与样式优化

  • 切换淡入:路由变化时给 .VPContent 注入 vp-fade-enter 类,300ms 级别的淡入上移动画,更自然。
  • 列表卡片:.notes-list 卡片化,标题悬停高亮,阅读更聚焦。
  • 分类交互:分类 chip 有轻微上移与颜色过渡,操作更灵动。
  • 时间线:归档页 <ul class="timeline"> 圆点时间线样式。
  • 可达性:prefers-reduced-motion: reduce 时关闭动效;全局颜色/背景过渡不突兀。

本地开发与部署

  • 本地
    • 安装:npm install
    • 开发:npm run dev
    • 构建:npm run build(输出到 dist/
    • 预览:npm run preview
  • 部署(静态平台)
    • dist/ 上传到任意静态托管(如 EdgeOne Pages、Netlify、Vercel、静态 OSS 等)。
    • 子路径部署时,确保鉴权使用的 withBase('/auth.json') 可正常取到资源。

常见问题与排查

  • ESM-only 报错:
    • 现已改为页面运行时 import.meta.glob 聚合,避免在 .vitepressrequire('vitepress') 的 CJS/ESM 冲突。
  • 中文乱码(Windows):
    • 统一使用 UTF-8 编码保存文件;若用 PowerShell 写文件,建议显式 -Encoding utf8
  • Vue 标签错误:
    • 遇到 “缺失闭合标签” 多源于模板中汉字/括号被错误编码或标签未闭合,统一修复为中文全角括号与完整 </span>
  • TS 语法错误:
    • 需在 Markdown SFC 使用 <script setup lang="ts">,否则会被按 JS 解析导致报错。

经验总结

  • 内容聚合用 import.meta.glob 足以覆盖多数静态场景,避免打包期引入 ESM-only 依赖。
  • 前端门禁要“可用但不过度依赖安全性”,真正的访问控制应交给边缘/服务端。
  • 样式与动效宜“克制”,优先强化信息结构与阅读体验。

后续路线

  • 标签页(按 tags 聚合)。
  • 首页「最近更新」模块与搜索联动。
  • 学习计划导入/导出(JSON),以及完成率统计图表。
  • 部署侧接入更强的访问控制(如边缘平台的登录/白名单/Basic Auth)。

—— 完 ———