Files
NewBlog/docs/操作指南.md
T

14 KiB
Raw Blame History

操作指南

这个博客的日常操作:写文章、写偶得、加照片、本地预览、部署上线。


0. 首次准备

cd /home/tianxuetao/文档/VermilionVoid-main
pnpm install          # 只需在第一次、或依赖变动后执行

平时不需要重复装依赖。


1. 本地预览(写得最多的一步)

pnpm dev

打开 http://localhost:4321。改任何文件浏览器会自动刷新,不用重启。

停止:在终端按 Ctrl + C。

端口被占用时 Astro 会自动换到 4322、4323……看终端输出的那行 Local 网址即可。


2. 写一篇正式文章

建文件

pnpm new-post "树莓派装 Docker 全程记录" --category 教程 --tags Docker,树莓派

常用选项:

选项 作用
--category 教程 分类,同时决定放进哪个子目录
--tags Docker,树莓派 标签,逗号分隔
--description "摘要" 摘要,用于 SEO 和列表卡片
--image /assets/images/xxx.webp 封面图
--file my-slug 自定义文件名(默认用标题)
--pinned 置顶
--draft 草稿,构建时不会输出

生成的文件长这样:

---
title: "树莓派装 Docker 全程记录"
published: 2026-09-14
description: "摘要"
tags:
  - "Docker"
  - "树莓派"
category: "教程"
---

写正文

直接在 --- 下面往下写 Markdown。支持:

  • 标题、列表、表格、引用、代码块(带行号和复制按钮)

  • 数学公式:$行内$ 和 $$独立成段$$

  • 提示框:

    > [!NOTE]
    > 这是一条提示。也可以用 TIP / IMPORTANT / CAUTION / WARNING
    
  • 图片:![说明](/assets/images/图片.webp)

不想用脚本

手动在 src/content/posts/ 下建 .md 文件也可以,只有 title 和 published 是必填的,其余字段都能省略。

加密文章(可选)

encrypted: true
password: "你的密码"

正文会被加密,需要输密码才能阅读。


3. 写一条「偶得」

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 里加一项:
{
  id: "我的相册",              // 必须和目录名一致
  name: "相册显示名",
  description: "一句话描述",
  location: "甘肃-张掖",       // 可选
  date: "2026-09-14",         // 可选
  tags: ["旅行"],              // 可选,用于索引页筛选
}

封面优先级:cover 字段 > 目录里的 cover.* 文件 > 第一张图。

📏 放进去之前先压图。 public/ 下的资源由服务器原样下发,不经过 Astro 优化。 一张 4K 原图可能十几 MB,会让页面加载非常慢。建议先压成 WebP 再放。


5. 检查与构建

pnpm check      # 类型 + 内容校验,frontmatter 写错会在这里报出来
pnpm build      # 构建到 dist/,并建立搜索索引
pnpm preview    # 本地预览构建产物(搜索功能只有这里才生效)

写完一篇后建议跑一次 pnpm check,能提前发现 frontmatter 字段写错。


6. 部署上线

./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。

只想更新书单(不动别的):

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):

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. 直接测后端:

    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 之后, 已经渲染过的文章不会重新跑插件 —— 你会以为改动没生效,其实是吃了缓存。

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 集合目前是空的,专题页会显示空态。

想回退到之前的状态

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)