Files
NewBlog/docs/操作指南.md
T
dsh cfcd24a3f8 回滚字体改动,恢复到 ef72d52 的状态
按站主要求,把字体相关改动整体回退。用 revert 而不是 reset —— 这些提交
已经推送并部署过,保留历史比改写历史安全。

撤销的两个提交:
- f56a6ed 门面字体改为霞鹜新致宋(LXGW Neo ZhiSong)
- e92ee27 字体系统重做:脱离 Google Fonts,统一思源黑/宋,门面加霞鹜文楷

回滚后恢复到:
- 西文与中文全部来自 Google Fonts
  (Inter / Noto Sans SC / Playfair Display / Noto Serif SC)
- 门面档用鸿蒙 Sans SC(jsdelivr 的 Regular + Semibold)
- --font-display-sans 回到 "HarmonyOS Sans SC"
- 站点名与首页那句话去掉 font-display-sans
- 操作指南里的字体说明表一并删除(缓存那条 FAQ 保留)

⚠️ 一并回来的已知问题
--font-mono 又变回 "Geist Mono", "Geist Mono Fallback" —— 这两个名字既没有
@font-face 也没装在机器上,font-mono 的回退链是断的,浏览器会退回默认字体
(不是等宽)。全站几十处 font-mono(时间线日期、偶得时间戳、内联代码…)受影响。
这是回滚的既定代价;要单独修的话就是一行。

验证:四个字体文件(BaseLayout / global.css / hero.tsx / site-header.astro)
与 ef72d52 逐字一致(git diff 为空),文档也一致。
2026-09-17 19:49:46 +08:00

357 lines
12 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.
# 操作指南
这个博客的日常操作:写文章、写偶得、加照片、本地预览、部署上线。
---
## 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`。
读完的书会自动出现在「书籍」区底部的「微信读书 · 已读完」分组里,不用手工搬。
**平时不用管**:`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 会把渲染好的文章缓存到 `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)
```