Files
NewBlog/README.md
T
dsh 686b1caa7d 新增 new-post 脚本与操作指南文档
- scripts/new-post.mjs + pnpm new-post:按标题建文章,支持 --category/--tags/
  --description/--image/--file/--pinned/--draft,标题里的冒号引号会正确转义
- docs/操作指南.md:写文章、发偶得、加相册、预览、检查、部署的完整流程
- 修复 astro check 报出的 2 个类型错误(gallery 索引页 querySelector 未指定
  HTMLElement,导致 dataset 不可用)。现在 pnpm check 为 0 error
2026-09-14 20:50:22 +08:00

256 lines
9.6 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",
version: "1.7.4",
stripTrailingSlash: true,
}
```
`twikooEnvId` 留空则整个评论区不渲染;也可以用环境变量 `PUBLIC_TWIKOO_ENV_ID` 覆盖,优先级更高。
前端实现在 `src/components/Comments.astro`,从 jsDelivr 加载 twikoo 脚本,另外处理了两件事:
- **切页重新挂载**:本站启用了 Astro 的 `ClientRouter`,组件监听 `astro:page-load` 事件重新初始化。
- **评论归属路径**:`trailingSlash` 是 `"always"`,但评论 key 统一去掉结尾斜杠、存成 `/posts/xxx`,与该路径在旧站点上的历史数据保持一致。改掉这条规则,已有评论会对不上。
主题原作者的自托管评论后端 `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/` 下的文章内容版权归作者所有,转载请注明出处。