build: 将构建工具链从 Bun 切换到 Node.js + pnpm - #361
Conversation
- 包管理器改用 pnpm,删除 bun.lock,提交 pnpm-lock.yaml - TS 脚本改由 node 直接执行(Node >= 23.6 原生类型擦除), 无需 tsx 等额外运行时;相应地把 scripts/pdf 与 epub 里的 相对导入由 .js 改为 .ts(Bun 会自动重映射,Node 不会) - trustedDependencies 迁移到 pnpm-workspace.yaml 的 allowBuilds - CI(check / deploy / release)改用 pnpm/action-setup + actions/setup-node,安装使用 --frozen-lockfile - dependabot 生态由 bun 改为 npm - 同步更新 README、CONTRIBUTING、AGENTS 等文档中的命令
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughChangesThe project switches from Bun to pnpm and Node.js. CI, deployment, release, package scripts, PDF/EPUB tooling, lockfile rules, and contributor documentation are updated. Package Manager Migration
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@README.md`:
- Line 112: Update README.md lines 112-112 and AGENTS.md lines 111-112 so the
format documentation matches package.json: describe pnpm run format as handling
Markdown, TypeScript, and JavaScript through Prettier plus autocorrect, and
document zig fmt as a separate required step; alternatively, add zig fmt to the
package.json format script and keep both documentation sites consistent.
- Line 86: Raise the minimum supported Node.js version to >=24 in package.json’s
engines.node and update the matching requirement in README.md:86,
scripts/pdf/AGENTS.md:29, and scripts/pdf/README.md:15.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: eac1cac8-06ed-4bc8-8a21-34daf438a236
⛔ Files ignored due to path filters (2)
bun.lockis excluded by!**/*.lockpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (22)
.github/CODEOWNERS.github/dependabot.yml.github/workflows/check.yml.github/workflows/deploy.yml.github/workflows/release.yml.gitignoreAGENTS.mdCONTRIBUTING.mdREADME.mdcourse/.vitepress/epub/README.mdcourse/.vitepress/epub/build.tscourse/about.mdcourse/appendix/community.mdcourse/appendix/well-known-lib.mdpackage.jsonpnpm-workspace.yamlscripts/pdf/AGENTS.mdscripts/pdf/README.mdscripts/pdf/build-fonts.tsscripts/pdf/main.tsscripts/pdf/parse.tsscripts/pdf/renderer.ts
macos-latest 已从 macOS 15 迁移到 macOS 26,Zig 在其上链接不到系统 libSystem,所有 libc 符号报 undefined,0.11 至 0.15.1 全部版本受影响。 固定到已知可用的 macos-15,同时避免 latest 漂移再次无声破坏构建。
- engines.node 由 >=23.6 改为 >=24:原生类型擦除虽自 23.6 起默认开启, 但 23.x 属奇数版本线且已 EOL,下限取受支持的 24 LTS,也与 CI 一致 - format 脚本实际只运行 prettier 与 autocorrect,不含 zig fmt, 修正 README 与 AGENTS 中的相关描述,并说明 Zig 需单独 zig fmt
lint job 此前既没有 checkout 代码,跑的又是会直接改写文件的 zig fmt, 命令在空目录里 0.06 秒退出,永远为绿,从未检查过任何 Zig 源文件。 - 补上 actions/checkout - zig fmt 改为 zig fmt --check - 固定 zig 0.16.0,此前用 master 会随上游变动而随机变红 - 排除 0.12 / 0.14 的 assembly.zig:旧内联汇编 clobbers 语法新版无法解析
markdown-it 15 起自带类型(dist/markdown-it.d.mts),导出形状与 @types/markdown-it 14 不同,tsc 报 3 处错误: - Options 更名为 MarkdownItOptions - 类型 MarkdownIt 需具名导入,default 导出的是 MarkdownItCallable - Renderer / Token 由主入口导出,lib/*.mjs 子路径已不在 exports 中 heading_open 的参数改由 RendererRule 上下文推断,不再手写标注 —— 手写的 签名与 15 的实际类型不符(options 为 Required<...>、env 可为 undefined)。 同时移除已过时的 @types/markdown-it 依赖。 产物验证:重新生成的 EPUB 除 UUID 与时间戳外与改动前逐字节一致。
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/workflows/check.yml (1)
28-29: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winSensitive Data Exposure (CWE-522): Insufficiently Protected Credentials
Exploitability: Theoretical
Disable persisted checkout credentials for the lint job.
actions/checkout@v4stores the authentication token in the local Git configuration by default. This job does not need authenticated Git commands. Setpersist-credentials: false.Proposed fix
- name: Checkout uses: actions/checkout@v4 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/check.yml around lines 28 - 29, Update the Checkout step in the lint job to set actions/checkout’s persist-credentials option to false, disabling storage of the authentication token while preserving the existing checkout behavior.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@course/.vitepress/epub/render.ts`:
- Around line 82-83: Initialize the fallback slugCounts map in render.ts with a
prototype-free object created via Object.create(null), preserving existing
counts when provided. Update the slugCounts seed in build.ts similarly so
constructor and __proto__ remain valid independent keys.
---
Nitpick comments:
In @.github/workflows/check.yml:
- Around line 28-29: Update the Checkout step in the lint job to set
actions/checkout’s persist-credentials option to false, disabling storage of the
authentication token while preserving the existing checkout behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 3fdecf1d-aa6e-42b3-9175-d0ff3a3fe923
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
.github/workflows/check.ymlcourse/.vitepress/epub/render.tspackage.json
💤 Files with no reviewable changes (1)
- package.json
goto-bus-stop/setup-zig 上游已归档停止维护,且仍 target Node 20, GitHub 已对其发出弃用警告。改用维护中的 mlugg/setup-zig@v2, 入参 version 同名兼容。 build.yml 中同时把 checkout 调整到 setup-zig 之前:checkout 的 clean 会清掉 setup-zig 恢复的本地 .zig-cache。矩阵作业按 Zig 版本 补上 cache-key,避免各版本互相覆盖缓存。
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/build.yml:
- Around line 33-35: Update the CI checkout step from actions/checkout@v4 to
actions/checkout@v5 in the workflow matrix, and validate the complete matrix
under Node.js 24. Keep mlugg/setup-zig unchanged until a Node.js 24-compatible
release is available.
- Line 33: 更新工作流中的 actions/checkout@v4 配置,禁用凭据持久化,并在工作流级别显式设置最小权限,仅授予 contents
读取权限;确保后续 zig build 执行不受信任代码时不会接触持久化的 GitHub token。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 1d5d80b9-4ca2-4928-98a4-bb4f8fd78015
📒 Files selected for processing (2)
.github/workflows/build.yml.github/workflows/check.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/check.yml
标题可被 slugify 成 constructor / __proto__ 等原型链上已有的名字, 用普通对象做计数表时: - constructor:首次出现即因继承而被判为重复,ID 变成 constructor-NaN - __proto__:赋值被当作设置原型而静默失效,计数永远存不进去, 同名标题拿到完全相同的 ID render.ts 的兜底与 build.ts 的逐章种子都改为 Object.create(null)。 课程现有标题尚未命中这些名字,重新生成的 EPUB 与改动前逐字节一致。
build.yml 与 check.yml 接受来自 fork 的 pull_request,且会执行 PR 中的 代码(zig build / pnpm install 的依赖构建脚本)。actions/checkout 默认把 github.token 写入 .git/config,可被这些代码读取。 - 两者显式声明 permissions: contents: read - 两者的 checkout 设置 persist-credentials: false - actions/checkout 由 v4 升至 v5(build / check / deploy / release / autocorrect),v4 仍声明 node20,GitHub 计划于今秋移除 mirror.yml 仍为 v3,涉及向外部镜像仓库推送,单独评估后再动。
背景
本仓库此前使用 Bun 作为包管理器和 TypeScript 运行时。本 PR 将其整体切换为 Node.js + pnpm。
改动内容
运行时
bun run *.ts改为node *.ts。Node >= 23.6 原生支持类型擦除,因此不需要引入tsx/ts-node等额外依赖。scripts/pdf/和course/.vitepress/epub/中的相对导入由.js改为.ts—— Bun 会把./foo.js自动重映射到./foo.ts,Node 不会。Bun.*/bun:*),这是切换成本较低的前提。包管理
bun.lock,改为提交pnpm-lock.yaml。package.json中的trustedDependencies迁移到pnpm-workspace.yaml的allowBuilds(core-js、esbuild)—— 这是 pnpm 11 的配置位置,不是package.json里的pnpm.onlyBuiltDependencies字段。packageManager: pnpm@11.3.0与engines.node: ">=23.6"。CI
check.yml/deploy.yml/release.yml:oven-sh/setup-bun改为pnpm/action-setup@v4+actions/setup-node@v4(node 24,开启cache: pnpm),安装统一使用pnpm install --frozen-lockfile。dependabot.yml:生态由bun改为npm,同时去掉不再需要的enable-beta-ecosystems。CODEOWNERS、.gitignore同步更新。文档
README、CONTRIBUTING、根目录与
scripts/pdf/的 AGENTS.md、course/about.md、PDF 与 EPUB 的 README 中的命令示例全部改为 pnpm / node。验证
本地已确认以下命令全部通过:
pnpm run build(VitePress 站点构建)pnpm run pdf:sample(PDF 导出)pnpm run epub(EPUB 导出)pnpm check(格式检查)说明
tsc -p course/.vitepress/epub目前有 3 处 markdown-it 相关的类型报错,位于render.ts。这是此前 markdown-it 升级到 15 引入的既有问题,与本次切换无关,该文件不在本 PR 的改动范围内。Summary by CodeRabbit
Chores
Documentation