Files
NewBlog/docs/操作指南.md

388 lines
14 KiB
Markdown
Raw Permalink 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.
# 操作指南
这个博客的日常操作:写文章、写偶得、加照片、本地预览、部署上线。
---
## 0. 首次准备
```bash
cd /home/tianxuetao/文档/VermilionVoid-main
pnpm install # 只需在第一次、或依赖变动后执行
```
平时不需要重复装依赖。
---
## 1. 本地预览(写得最多的一步)
```bash
pnpm dev
```
打开 **http://localhost:4321**。改任何文件浏览器会自动刷新,不用重启。
停止:在终端按 `Ctrl + C`。
> 端口被占用时 Astro 会自动换到 4322、4323……看终端输出的那行 `Local` 网址即可。
---
## 2. 写一篇正式文章
### 建文件
```bash
pnpm new-post "树莓派装 Docker 全程记录" --category 教程 --tags Docker,树莓派
```
常用选项:
| 选项 | 作用 |
|---|---|
| `--category 教程` | 分类,同时决定放进哪个子目录 |
| `--tags Docker,树莓派` | 标签,逗号分隔 |
| `--description "摘要"` | 摘要,用于 SEO 和列表卡片 |
| `--image /assets/images/xxx.webp` | 封面图 |
| `--file my-slug` | 自定义文件名(默认用标题) |
| `--pinned` | 置顶 |
| `--draft` | 草稿,构建时不会输出 |
生成的文件长这样:
```yaml
---
title: "树莓派装 Docker 全程记录"
published: 2026-09-14
description: "摘要"
tags:
- "Docker"
- "树莓派"
category: "教程"
---
```
### 写正文
直接在 `---` 下面往下写 Markdown。支持:
- 标题、列表、表格、引用、代码块(带行号和复制按钮)
- 数学公式:`$行内$` 和 `$$独立成段$$`
- 提示框:
```markdown
> [!NOTE]
> 这是一条提示。也可以用 TIP / IMPORTANT / CAUTION / WARNING
```
- 图片:`![说明](/assets/images/图片.webp)`
### 不想用脚本
手动在 `src/content/posts/` 下建 `.md` 文件也可以,**只有 `title` 和 `published` 是必填的**,其余字段都能省略。
### 加密文章(可选)
```yaml
encrypted: true
password: "你的密码"
```
正文会被加密,需要输密码才能阅读。
---
## 3. 写一条「偶得」
```bash
pnpm new-thought "换了散热,温度降了 15 度。" --location 张掖 --tags 硬件
```
| 选项 | 作用 |
|---|---|
| `--title` | 可选标题 |
| `--location` | 地点,显示在日期旁 |
| `--weather` | 天气 |
| `--images a.png,b.png` | 配图,逗号分隔 |
| `--tags 生活,硬件` | 标签 |
| `--pinned` | 置顶 |
> ⚠️ **`published` 一定要带时区**(脚本会自动写成 `2026-09-14T12:36:47.215Z`)。
> 手写成不带时区的 `2026-09-14 12:36`,YAML 会按 UTC 解析,**显示的日期会差一天**。
偶得页有两种模式:**专注**(一次一条,←/→ 切换)和**时间线**(按年份分组 + 标签筛选)。
---
## 4. 加照片到相册
照片放在 `public/gallery/<相册id>/`,**构建时自动扫描目录**,不用在配置里逐个登记。
加一个新相册 = 两步:
1. 建目录并放照片:`public/gallery/我的相册/`
2. 在 `src/data/gallery.ts` 的 `albums` 里加一项:
```ts
{
id: "我的相册", // 必须和目录名一致
name: "相册显示名",
description: "一句话描述",
location: "甘肃-张掖", // 可选
date: "2026-09-14", // 可选
tags: ["旅行"], // 可选,用于索引页筛选
}
```
封面优先级:`cover` 字段 > 目录里的 `cover.*` 文件 > 第一张图。
> 📏 **放进去之前先压图。** `public/` 下的资源由服务器原样下发,**不经过 Astro 优化**。
> 一张 4K 原图可能十几 MB,会让页面加载非常慢。建议先压成 WebP 再放。
---
## 5. 检查与构建
```bash
pnpm check # 类型 + 内容校验,frontmatter 写错会在这里报出来
pnpm build # 构建到 dist/,并建立搜索索引
pnpm preview # 本地预览构建产物(搜索功能只有这里才生效)
```
写完一篇后建议跑一次 `pnpm check`,能提前发现 frontmatter 字段写错。
---
## 6. 部署上线
```bash
./deploy.sh
```
它会构建一次,然后 rsync 到树莓派和云服务器,覆盖生产前会问你一句确认。
两个目标都是 **Caddy** 在服务,而且都开了压缩(`twikoo.min.js` 506 KB → 160 KB)。
- 云服务器:1Panel 管的 Caddy 容器,配置 `/opt/1panel/apps/caddy/caddy/data/conf/Caddyfile`
- 树莓派:Caddy 容器 `blog-caddy`,配置 `/home/pi/caddy/Caddyfile`
| 命令 | 用途 |
|---|---|
| `./deploy.sh` | 构建 + 部署两个目标 |
| `./deploy.sh -y` | 同上,跳过确认(适合脚本) |
| `./deploy.sh --pi-only` | 只推树莓派,先在内网看效果 |
| `./deploy.sh --cloud-only` | 只推云服务器(正式上线) |
| `./deploy.sh --dry-run` | 空跑,只显示会同步哪些文件 |
| `./deploy.sh --skip-build` | 不重新构建,直接推现有 `dist/` |
推荐节奏:先 `--pi-only` 在树莓派上确认没问题,再 `--cloud-only` 上生产。
> 目标地址和 SSH 密钥在 `deploy.sh` 顶部的**配置区**。
> 脚本在构建失败或产物异常时会**直接中止**——因为推送用的是 `rsync --delete`,
> 拿一个残缺的 `dist/` 上去会清空线上目录。
---
## 7. 改站点信息
日常最常改的三个文件:
| 想改什么 | 改哪里 |
|---|---|
| 站名、域名、描述、主题色、统计 | `src/data/site.ts` |
| 昵称、签名、头像、GitHub/邮箱 | `src/data/profile.ts` |
| 首页打字机文案 | `src/components/hero.tsx` 顶部的 `phrases` |
主题色只改 `site.ts` 里的 `themeHue` 一个数字:`0` 红、`25` 朱红(当前)、`200` 青、`250` 蓝绿、`345` 粉。
---
## 7.5 刷新「最近在读」
书架分成两个页面:**在读** `/bookshelf/`(顶部导航「书架」的落点)、**书籍** `/bookshelf/books/`,侧栏「馆藏」互相跳转。
「在读」是从微信读书抓来的,数据存在 `src/data/reading.json`。
**只想更新书单**(不动别的):
```bash
pnpm reading
```
会打印抓到的每本书和进度。**默认抓整架**;想只抓最近动过的几本就 `pnpm reading --top 12`。
读完的书会自动出现在「书籍」区底部的「微信读书 · 已读完」分组里,不用手工搬。
**有声书(专辑)**:同一次请求里还会抓书架上的专辑,写进 `reading.json` 的 `albums` 字段。
「在读」页会自动多出一个「有声书」区块 —— 但没有专辑时整块不显示,所以现在看不到是正常的。
专辑没有阅读进度也没有跳转链接(微信读书那边就没给),卡片只显示集数、完结状态和最近收听。
`--top` 只作用于书,专辑一次全取;`secret: 1` 的私密收听同样会被过滤掉。
**平时不用管**:`pnpm build` 和 `./deploy.sh` 都会自动先抓一次。抓不到就沿用上一次的数据,**不会让部署失败**。
**首次配置**(只做一次):
1. 打开 <https://weread.qq.com/r/weread-skills> 扫码,拿到 `wrk-` 开头的 Key
2. 在项目根目录的 `.env` 里加一行:
```
WEREAD_API_KEY=wrk-你的key
```
`.env` 已被 gitignore,不会提交,也不会随 `deploy.sh` 上传到服务器。
不想出现在页面上就改 `scripts/fetch-reading.mjs` 里的过滤条件(默认跳过私密阅读和从没打开过的书)。
---
## 8. 常见问题
**改了文件但浏览器没变**
先手动刷新。若仍无效,`Ctrl + C` 停掉再 `pnpm dev` 重启。
**构建时报 `ENOSPC: System limit for number of file watchers reached`**
系统的 inotify 监视器配额用完了,不是代码问题。页面照常访问,但热更新可能失效。
彻底解决需要放宽内核参数(要 sudo):
```bash
sudo sysctl fs.inotify.max_user_watches=524288
```
**偶得的日期差一天**
看第 3 节:`published` 必须带时区。
**图片不显示**
检查路径是否以 `/` 开头(`/assets/images/x.webp`),以及文件是否真在 `public/` 下对应位置。
注意 `public/` 里的文件路径就是 URL 路径,**没有 `public` 这一段**。
**评论区空白 / 不显示**
先确认页面类型——评论**只出现在文章页、关于页、友链页**,首页、偶得、相册、书架、专题都没有,这是正常的。
如果文章页也是空的,按顺序查:
1. `src/data/comments.ts` 里的 `twikooEnvId` 是否填了(留空则整个评论区不渲染)
2. 打开浏览器控制台,看有没有 `[twikoo] 初始化失败` 或 404
3. 确认 `public/assets/js/twikoo.min.js` 和 `public/assets/css/twikoo.css` 都在,且版本与后端一致
4. 直接测后端:
```bash
curl -s -X POST https://twikoo.tianxuetao.top \
-H 'Content-Type: application/json' \
-d '{"event":"GET_FUNC_VERSION"}'
```
正常会返回 `{"code":0,"version":{"VERSION":"1.7.20"}}`。若版本和前端脚本不一致,去
<https://cdn.jsdelivr.net/npm/twikoo@<后端版本>/dist/> 下载 `twikoo.min.js` 和 `twikoo.css` 两个文件一起替换。
> 评论按**页面路径**归属,且存的是浏览器提交的**百分号编码**路径。
> 换域名或改 URL 结构后,老评论会因为路径对不上而「消失」——数据还在后端,只是不再匹配。
**评论区排版错乱(按钮变得巨大、表情面板塌成一列、「选择文件」露出来)**
症状是**点链接切到另一篇文章后才崩,按 F5 刷新就正常**。
原因:twikoo 脚本只执行一次,第二次进文章页时不会重新执行;而 `ClientRouter` 切页时会清掉
它运行时注入到 `<head>` 的 `<style>`,样式就没了。
修复早已内置:`Comments.astro` 里用静态 `<link>` 引入 `public/assets/css/twikoo.css`(放在
`twikoo-custom.css` 之前)。如果又出现这个症状,先确认这两行 `<link>` 还在,
并且 `public/assets/css/twikoo.css` 没被误删。
**「最近在读」空了 / 数据不更新**
先看构建日志里有没有 `⚠️ 抓取失败,继续用上一次的数据构建`,后面会跟具体原因:
| 日志里的话 | 怎么办 |
|---|---|
| `WEREAD_API_KEY 无效或已过期` | Key 失效了,重新扫码拿一个,更新 `.env` |
| `缺少 WEREAD_API_KEY` | `.env` 里没配,见第 7.5 节 |
| `fetch failed` / 超时 | 网络问题,重跑 `pnpm reading` 即可 |
**重要**:以上任何一种都**不会**让 `pnpm build` 失败 —— 页面会继续用 `src/data/reading.json` 里上一次的数据。所以「站点发布成功但书单是旧的」是正常现象,不是 bug。
如果连空态提示都看不到,检查 `src/data/reading.json` 是否存在(这个文件要提交进 git)。
**同样的 Markdown,偶得和文章的渲染结果不一样**
因为**它们走的根本不是同一套渲染器**:
| | 渲染器 | 位置 |
|---|---|---|
| 文章 | Astro 内容管线 → **Sätteri**(`astro.config.mjs` 里开了 `gfm`)| `render(post)` |
| 偶得 | **markdown-it**,裸配置 | `src/lib/thoughts.ts` 里的 `new MarkdownIt()` |
裸的 markdown-it 不含 GFM 扩展,所以要什么能力就得自己挂插件。
目前只挂了任务列表(`src/plugins/markdown-it/task-lists.mjs`),
它输出的 HTML 刻意和 Sätteri 那边对齐(`contains-task-list` /
`task-list-item` / `<input type="checkbox" disabled>`),以后加样式两边通用。
**已知还缺的 GFM 能力**(偶得里写了不会生效,文章里正常):
- 裸链接自动转链接(markdown-it 需要 `linkify: true`,当前没开)
- 脚注
- 数学公式(`$…$`)—— 文章那边有 KaTeX,偶得没有
- Obsidian callout(`> [!tip]`)
- 智能标点(引号、破折号)
要在偶得里补哪一项,就先看它在文章那边是由哪个管线功能提供的,再决定是给
markdown-it 挂插件、还是把偶得也改用 Astro 内容管线(后者改动大:偶得页是
React island,内容要序列化成 HTML 字符串传给客户端)。
**改了 markdown 插件却不生效**
Astro 会把渲染好的文章缓存到 `node_modules/.astro`,而这个缓存**只按 markdown
文件内容算 key,不看插件代码**。所以改完 `src/plugins/satteri/*.mjs` 之后,
已经渲染过的文章不会重新跑插件 —— 你会以为改动没生效,其实是吃了缓存。
```bash
rm -rf node_modules/.astro .astro && pnpm build
```
(这个坑是给标题锚点补 `aria-label` 时踩到的:插件明明改了,
产物里的 HTML 却还是老样子。)
**`pnpm dev` 启动时满屏刷红**
历史上踩过两个独立的原因,都已修好,这里记下来免得再犯:
1. **源码里出现字面量的 script 开标签**(`Sketch.astro` 的 frontmatter 里曾经有)。
Astro 编译器靠**扫描源码文本**收集内联脚本,它分不清「这是真的标签」还是
「在字符串/注释里」。一旦扫到,就会把后面的内容当成组件脚本交给 Vite 解析,
报 `Expected "}" but found "{"` 或 `Unexpected "。"`,整个 `/src` 刷红。
→ 用 `"\x3Cscript>"` 拼出来。**注释里也不能写**,第一版就是栽在注释上。
2. **`.pnpm-store` 被 Vite 的 watcher 一起监听**。它是 pnpm 的内容寻址仓库,
5.4 万个文件 / 672MB,直接把 inotify 撑爆(`max_user_watches = 65536`),
报 `ENOSPC: System limit for number of file watchers reached`。
→ 已在 `astro.config.mjs` 里排除:`vite.server.watch.ignored: ["**/.pnpm-store/**"]`。
看到 `[WARN] [glob-loader] No files found ... src/content/studies` 是**正常的** ——
`studies` 集合目前是空的,专题页会显示空态。
**想回退到之前的状态**
```bash
git log --oneline # 看提交
git reset --hard <提交号>
```
---
## 附:目录速查
```
src/content/posts/ 文章(按分类分子目录)
src/content/thoughts/ 偶得
src/content/studies/ 专题(目前为空)
src/data/site.ts 站点配置
src/data/profile.ts 个人信息
src/data/gallery.ts 相册配置
src/data/comments.ts 评论配置
src/components/hero.tsx 首页打字机文案
public/assets/images/ 文章配图
public/gallery/ 相册照片
scripts/ 辅助脚本
dist/ 构建产物(gitignore)
```