Skip to content

build: 将构建工具链从 Bun 切换到 Node.js + pnpm - #361

Merged
jinzhongjia merged 8 commits into
mainfrom
bunjs-to-nodejs-pnpm
Aug 4, 2026
Merged

build: 将构建工具链从 Bun 切换到 Node.js + pnpm#361
jinzhongjia merged 8 commits into
mainfrom
bunjs-to-nodejs-pnpm

Conversation

@jinzhongjia

@jinzhongjia jinzhongjia commented Aug 4, 2026

Copy link
Copy Markdown
Member

背景

本仓库此前使用 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 专有 API(Bun.* / bun:*),这是切换成本较低的前提。

包管理

  • 删除 bun.lock,改为提交 pnpm-lock.yaml
  • package.json 中的 trustedDependencies 迁移到 pnpm-workspace.yamlallowBuildscore-jsesbuild)—— 这是 pnpm 11 的配置位置,不是 package.json 里的 pnpm.onlyBuiltDependencies 字段。
  • 新增 packageManager: pnpm@11.3.0engines.node: ">=23.6"

CI

  • check.yml / deploy.yml / release.ymloven-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

    • Switched project tooling and automated workflows from Bun to pnpm.
    • Standardized dependency installation with the project lockfile and Node.js 24 support.
    • Updated dependency, deployment, release, validation, and macOS build workflows.
    • Updated PDF and EPUB generation commands to use Node.js and pnpm.
  • Documentation

    • Updated setup, contribution, development, and export guides with revised requirements and commands.
    • Clarified lockfile, formatting, and build requirements across project documentation.
    • Node.js 24 or newer is now required for local development.

- 包管理器改用 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 等文档中的命令
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

The 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

Layer / File(s) Summary
Runtime and build tooling
package.json, pnpm-workspace.yaml, course/.vitepress/epub/*, scripts/pdf/*
Package scripts and PDF/EPUB tooling now use Node.js, pnpm, and TypeScript source imports. EPUB rendering uses public MarkdownIt types and handles absent rendering environments.
CI and dependency automation
.github/*, .gitignore
Automation uses Node.js 24, pnpm caching, frozen-lockfile installs, Zig formatting checks, and pnpm lockfile ownership.
Documentation and contributor guidance
AGENTS.md, README.md, CONTRIBUTING.md, course/*, scripts/pdf/*.md
Documentation now specifies pnpm commands, Node.js requirements, and pnpm lockfile usage.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: jiacai2050, xihale

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change from Bun to Node.js and pnpm.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bunjs-to-nodejs-pnpm

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6e5d810 and 5bb3e67.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is 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
  • .gitignore
  • AGENTS.md
  • CONTRIBUTING.md
  • README.md
  • course/.vitepress/epub/README.md
  • course/.vitepress/epub/build.ts
  • course/about.md
  • course/appendix/community.md
  • course/appendix/well-known-lib.md
  • package.json
  • pnpm-workspace.yaml
  • scripts/pdf/AGENTS.md
  • scripts/pdf/README.md
  • scripts/pdf/build-fonts.ts
  • scripts/pdf/main.ts
  • scripts/pdf/parse.ts
  • scripts/pdf/renderer.ts

Comment thread README.md Outdated
Comment thread README.md Outdated
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 与时间戳外与改动前逐字节一致。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/check.yml (1)

28-29: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Sensitive Data Exposure (CWE-522): Insufficiently Protected Credentials

Exploitability: Theoretical

Disable persisted checkout credentials for the lint job.

actions/checkout@v4 stores the authentication token in the local Git configuration by default. This job does not need authenticated Git commands. Set persist-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

📥 Commits

Reviewing files that changed from the base of the PR and between d7c3f26 and 746490d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • .github/workflows/check.yml
  • course/.vitepress/epub/render.ts
  • package.json
💤 Files with no reviewable changes (1)
  • package.json

Comment thread course/.vitepress/epub/render.ts Outdated
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,避免各版本互相覆盖缓存。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 746490d and 1a99154.

📒 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

Comment thread .github/workflows/build.yml Outdated
Comment thread .github/workflows/build.yml Outdated
标题可被 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,涉及向外部镜像仓库推送,单独评估后再动。
@jinzhongjia
jinzhongjia merged commit cdb497a into main Aug 4, 2026
38 checks passed
@jinzhongjia
jinzhongjia deleted the bunjs-to-nodejs-pnpm branch August 4, 2026 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant