Files
NewBlog/docs/操作指南.md
T
dsh 9c0851fd12 修复 pnpm dev 启动刷红:Sketch.astro 脚本误识别 + .pnpm-store 撑爆 inotify
两个独立问题叠在一起,用户看到的只是第一个(扫描失败会中止启动,
第二个来不及暴露)。

1) Sketch.astro 的 frontmatter 里出现字面量的 script 开标签
   Astro 编译器靠扫描源码文本收集内联脚本,分不清真标签和字符串/注释。
   原代码用模板字符串拼 iframe 里的 resize 脚本,那个字面量开标签被当成
   组件脚本抽出来交给 Vite,里面的 ${JSON.stringify(...)} 直接报
   `Expected "}" but found "{"`,dev 依赖扫描失败、整个 /src 刷红。
   -> 改成 "\x3Cscript>" / "\x3C/script>" 拼接。
   注意闭标签原本写作 <\/script> 所以没被误判,只有开标签要处理。
   修完第一版又把解释写进注释、注释里带了字面量开标签,于是换了条错误
   (`Unexpected "。"`)继续报;这次注释也改成不带字面量的写法。

2) .pnpm-store 被 Vite 的 watcher 一起监听
   项目根目录下的 .pnpm-store 是 pnpm 内容寻址仓库(54269 个文件 / 672MB,
   已被 .gitignore 忽略),Vite 默认 watch 项目根,直接撑爆 inotify
   (max_user_watches = 65536),启动后无限刷
   `ENOSPC: System limit for number of file watchers reached`。
   -> astro.config.mjs 加 vite.server.watch.ignored: ["**/.pnpm-store/**"]。

顺带:package.json 加 "type": "module",消掉 Node 对
src/plugins/*.js 的 MODULE_TYPELESS_PACKAGE_JSON 警告(两个文件本来就是 ESM)。

验证
- 删掉 node_modules/.vite 强制重新做依赖扫描后启动 pnpm dev:
  ERROR 0 / Failed to scan 0 / ENOSPC 0,ready in 496ms
  /、/bookshelf/、/bookshelf/books/ 均 200
- pnpm build 退出码 0,MODULE_TYPELESS 警告 0
- 仅剩 [WARN] glob-loader 提示 src/content/studies 为空,属预期
- 操作指南补了这条 FAQ,说明两个原因和"注释里也不能写"这个坑
2026-09-15 12:22:44 +08:00

11 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 到树莓派和云服务器,覆盖生产前会问你一句确认。

命令 用途
./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。

读完的书会自动出现在「书籍」区底部的「微信读书 · 已读完」分组里,不用手工搬。

平时不用管: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)。

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)