Files
NewBlog/README.md
T
dsh 0b99eabfbe 评论区改为自托管 twikoo 前端,并适配主题
- 前端脚本从 jsDelivr 改为自托管 public/assets/js/twikoo.min.js,
  版本与后端对齐(1.7.20)。国内访问 jsDelivr 实测 3 秒以上且常被墙,
  是评论区空白的根因
- 新增 public/assets/css/twikoo-custom.css 主题适配层:选择器加 #twikoo
  前缀以覆盖运行时注入的样式,颜色引用主题变量,自动跟随亮/暗色
- 修复首屏重复初始化:astro:page-load 在首屏也会触发,用 dataset.mounted 去重
- 评论配置移除已无用的 version 字段;README 与操作指南同步更新
2026-09-14 20:58:37 +08:00

261 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 时之刃的小站
个人博客源码 —— [tianxuetao.top](https://tianxuetao.top)
一个基于 Astro 的静态博客,主题为 [VermilionVoid](https://github.com/Lapis0x0/VermilionVoid)。除了常规的文章系统,还有碎碎念、读书/论文/漫画书架、学习追踪与加密文章。
站点配置集中在两个文件,改站名或换域名通常只需要动第一个:
| 文件 | 管什么 |
|---|---|
| `src/data/site.ts` | 站名、域名、描述、关键词、主题色、统计分析 |
| `src/data/profile.ts` | 昵称、签名、头像、社交链接 |
评论配置在 `src/data/comments.ts`。
> 日常操作(写文章、发偶得、加照片、部署)看 **[docs/操作指南.md](docs/操作指南.md)**,那份更偏"照着做";本文偏项目结构与原理。
---
## 技术栈
| 层 | 选型 |
|---|---|
| 框架 | [Astro](https://astro.build) 5(`output: "static"` 纯静态) |
| 交互组件 | React 19(islands)+ Radix UI + Tailwind CSS 4 |
| 代码块 | Expressive Code(行号、折叠、语言徽章、自定义复制按钮) |
| 数学公式 | remark-math + KaTeX |
| 站内搜索 | Pagefind(构建时索引) |
| 页面切换 | Swup |
| 部署 | `./deploy.sh`(rsync 到树莓派 + 云服务器) |
| 评论系统 | 自托管的 [twikoo](https://twikoo.js.org)(见下) |
包管理器是 **pnpm**。
## 快速开始
```bash
pnpm install
```
```bash
pnpm dev
```
| 命令 | 作用 |
|---|---|
| `pnpm dev` | 本地开发服务器(默认 `http://localhost:4321`) |
| `pnpm build` | 构建到 `dist/`,并跑 Pagefind 建立搜索索引 |
| `pnpm preview` | 本地预览构建产物 |
| `pnpm check` | Astro 的类型与内容校验(本项目没有单元测试框架,这就是唯一的自动检查) |
| `pnpm new-thought "..."` | 快速创建一条「偶得」(见下) |
## 项目结构
```
src/
├── pages/ 路由入口(每个文件对应一个 URL)
├── layouts/ 页面骨架
├── components/ Astro / React 组件,可复用的原子组件放 components/ui/
├── content/ Markdown 内容集合(见下)
├── data/ 站点配置:站点信息、个人信息、相册、评论、友链
├── styles/ 全局 CSS
├── plugins/ 自定义 remark / rehype / Expressive Code 插件
├── lib/ hooks/ 支撑逻辑
public/ 原样拷贝到产物根目录的静态资源
├── assets/images/ 文章配图
├── gallery/<id>/ 相册照片,构建时自动扫描
scripts/ 内容工具脚本
```
## 写作
内容集合定义在 `src/content/config.ts`,共三个:
### `posts` —— 正式文章
放在 `src/content/posts/`,支持子目录分类。
```yaml
---
title: 文章标题
published: 2026-08-17
updated: 2026-08-18 # 可选
description: 摘要 # 可选,用于 SEO 和卡片
image: /images/cover.webp # 可选,封面
tags: [Astro, 前端]
category: TechnicalTutorials
pinned: false # 置顶
draft: false # 草稿不会被构建
---
```
**加密文章**:给 frontmatter 加上 `encrypted: true` 和 `password: "你的密码"`,该文章正文会被加密,需输入密码才能阅读。适合半公开的内容。
**免责声明**:`disclaimer` 字段可以引用 `src/data/disclaimers.ts` 里预设的声明文案。
### `thoughts` —— 偶得
短内容,放在 `src/content/thoughts/`。只有 `published` 是必填,其余可选。
```yaml
---
published: 2026-09-14T12:36:47.215Z # 必填。务必带时区,见下方说明
title: 可选标题
location: 张掖 # 可选,显示在日期旁
weather: 晴 27°C # 可选
images: # 可选,public 下的绝对路径
- /gallery/GalleryFav/某图.webp
tags: [生活]
pinned: false # 可选,置顶排在最前
---
```
用脚本创建更省事:
```bash
pnpm new-thought "换了散热,温度降了 15 度。" --location 张掖 --tags 硬件 --pinned
```
> **`published` 一定要带时区**(`2026-09-14T12:36:47Z` 这种)。写成不带时区的 `2026-09-14 12:36`,YAML 会按 UTC 解析,显示时会偏移。偶得页按 `src/data/site.ts` 的 `timezone` 渲染,所以带时区的时间才会显示正确。
### `studies` —— 专题
```yaml
---
title: 主题
status: 在读 # 在读 | 沉淀中 | 暂搁 | 已结
started: 2026-08
field: 领域 # 可选
subtitle: 副标题 # 可选
epigraph: 题记 # 可选
---
```
## 相册
照片放在 `public/gallery/<相册id>/`,构建时**自动扫描目录**,不需要在配置里逐个列出。
新增一个相册 = 两件事:
1. 在 `src/data/gallery.ts` 的 `albums` 里加一项(`id` 要和目录名一致)
2. 建目录 `public/gallery/<id>/` 并放照片
```ts
{
id: "GalleryFav",
name: "喜欢的壁纸",
description: "相册描述",
location: "甘肃-张掖",
date: "2026-07-18",
tags: ["壁纸", "收藏"], // 用于索引页筛选
}
```
封面优先级:`cover` 字段 > 目录里的 `cover.*` 文件 > 第一张图。
> 照片是原样下发的静态资源,**不经过 Astro 优化**。分辨率高的图建议先压成 WebP 再放进来,否则单页可能几十 MB。
## 自定义
想把这个博客改成你自己的,主要改这几处:
| 想改什么 | 改哪里 |
|---|---|
| 站名、域名、描述、主题色、统计 | `src/data/site.ts` |
| 昵称、签名、头像、社交链接 | `src/data/profile.ts` |
| 相册 | `src/data/gallery.ts` + `public/gallery/` |
| 评论(twikoo) | `src/data/comments.ts` |
| 友链列表 | `src/data/friends.json` |
| 首页打字机文案 | `src/components/hero.tsx` 顶部的 `phrases` |
| 导航栏、页脚 | `src/components/site-header.astro`、`src/components/footer.tsx` |
| 配色与全局样式 | `src/styles/global.css` |
| 代码块主题 | `astro.config.mjs` 里 `expressiveCode` 的 `themes` |
| 免责声明模板 | `src/data/disclaimers.ts` |
| 头像、favicon 等静态资源 | `public/` |
代码风格:Astro/TS/TSX 一律 2 空格缩进。组件命名 `PascalCase` 与 `kebab-case` 混用,跟着所在目录的既有风格走即可。项目没有配 formatter,改动尽量贴合周围代码。
## 书架数据
书架页的数据来自这三个文件,由 `src/components/bookshelf-content.astro` 在**构建时 import**(所以文件必须存在,删掉会导致构建失败):
- `public/data/books.json`
- `public/data/papers.json`
- `public/data/comics.json`
目前都是空的 `{"data":{"items":[],"total":0}}`,所以书架页显示为空。要填充就按同样的结构往 `items` 里加记录。
## 部署
主用 `./deploy.sh`,构建后 rsync 到树莓派和云服务器:
```bash
./deploy.sh # 构建 + 部署到两个目标(覆盖生产前会确认)
./deploy.sh --pi-only # 只推树莓派(内网预览)
./deploy.sh --cloud-only # 只推云服务器
./deploy.sh --dry-run # 只显示 rsync 会做什么
./deploy.sh --skip-build # 不重新构建,推现有 dist/
./deploy.sh -y # 跳过确认
```
目标地址和 SSH 密钥在脚本顶部的**配置区**。脚本会在构建失败或产物异常时**直接中止**——因为推送用的是 `rsync --delete`,拿一个残缺的 `dist/` 上去会清空线上目录。
`vercel.json` 仍然保留,把它接到 Vercel 也可以。走 Vercel 时需要在项目里配置环境变量 `PUBLIC_TWIKOO_ENV_ID`(评论后端地址,留空则不渲染评论区);本地开发写进 `.env`(已 gitignore),参考 `.env.example`。
---
## 评论系统
使用 [twikoo](https://twikoo.js.org),后端为自托管实例。
配置在 `src/data/comments.ts`:
```ts
export const commentConfig = {
twikooEnvId: "https://twikoo.tianxuetao.top",
lang: "zh-CN",
stripTrailingSlash: true,
}
```
`twikooEnvId` 留空则整个评论区不渲染;也可以用环境变量 `PUBLIC_TWIKOO_ENV_ID` 覆盖,优先级更高。
**前端脚本不走 CDN**,而是自托管的 `public/assets/js/twikoo.min.js`。国内访问 jsDelivr 很不稳定(实测 3 秒以上,且常被墙),走 CDN 会让评论区长时间空白甚至加载不出来。该文件的版本要与后端保持一致(当前都是 **1.7.20**,可用 `GET_FUNC_VERSION` 查后端版本),升级后端时记得同步替换它。
主题适配样式在 `public/assets/css/twikoo-custom.css`。twikoo 的样式是运行时注入 `<head>` 的、会排在后面,所以那里的选择器统一加了 `#twikoo` 前缀来提高优先级,颜色引用主题变量因而自动跟随亮/暗色。
前端逻辑在 `src/components/Comments.astro`,处理了两件事:
- **切页重新挂载**:本站启用了 Astro 的 `ClientRouter`。注意 `astro:page-load` 在**首屏也会触发**,所以用 `dataset.mounted` 标记防止重复初始化;切页后是新容器、没有该标记,会正常重新挂载。
- **评论归属路径**:`trailingSlash` 是 `"always"`,但评论 key 统一去掉结尾斜杠。浏览器提交的是**百分号编码**过的 `location.pathname`(如 `/posts/%E7%94%9F%E6%B4%BB/...`),后端按原样存储和匹配 —— 所以去斜杠后的编码路径正好与历史数据一致。改掉这条规则,老评论就会对不上。
评论出现在:文章页、关于页、友链页。
主题原作者的自托管评论后端 `cwd-api/` 已随迁移移除。
---
## Fork 须知
如果你要基于这个仓库搭自己的博客,至少改这几处:
1. **`src/data/site.ts`** —— 站名、域名、描述、主题色,以及 `analytics` 里的统计 ID(每一项留空就不加载对应脚本)。`astro.config.mjs` 的 `site` 已经引用这里的 `site.url`,不用单独改。
2. **`src/data/profile.ts`** —— 昵称、签名、头像、社交链接。
3. **`src/data/comments.ts`** —— twikoo 后端地址,填你自己部署的实例。
4. **`src/data/friends.json`** —— 友链列表。
另外这几处仍是从主题原作者仓库带过来的内容,按需清空替换:
- `src/content/` 下的文章、碎碎念、学习专题
- `public/data/*.json` 的书架数据
- `public/images/vote/` 的赞赏收款码(关于页已不再引用)
## 致谢
文章系统的部分设计参考了 [Fuwari](https://github.com/saicaca/fuwari),主题为 [VermilionVoid](https://github.com/Lapis0x0/VermilionVoid)。
## 许可
代码部分可自由参考取用。`src/content/` 下的文章内容版权归作者所有,转载请注明出处。