部署
主题是普通的 VuePress 2 主题,所以文档站的部署方式和任何 VuePress 站点一样:先构建, 再托管 docs/.vuepress/dist 目录。
npm install
npm run docs:build # 先把主题构建到 lib/,再把站点构建到 docs/.vuepress/distdocs:build 会先构建主题,所以宿主只需要这一条命令:
install: npm ci
build: npm run docs:build
output: docs/.vuepress/dist仓库根目录下的 edgeone.json 把这四项写死了,EdgeOne Pages 会自动读取, 所以控制台里不用再手填:
{
"$schema": "https://edgeone.ai/schema/edgeone.json",
"installCommand": "npm ci",
"buildCommand": "npm run docs:build",
"outputDirectory": "docs/.vuepress/dist",
"nodeVersion": "22.20"
}安装命令
无论用什么平台,构建都必须从仓库根目录运行,并且必须在构建站点之前先构建主题。 docs/.vuepress/config.js 从 ../../lib/node/index.js 导入主题,而 lib/ 是生成物 —— 它没有被提交。这也是 docs:build 写成 node scripts/build.mjs && vuepress build docs、而不是裸 vuepress build docs 的原因。
顺序很重要。在全新检出上单跑 vuepress build docs,在渲染任何东西之前就会失败:
[UNRESOLVED_IMPORT] Could not resolve '../../lib/node/index.js' in docs/.vuepress/config.js重复构建是无害的 —— scripts/build.mjs 会整体替换 lib/。如果宿主需要分开的构建 命令,npm run build && npm run docs:build 等价且依然正确。
npm ci 需要 lockfile 与 package.json 同步。如果你手工改过依赖,先跑一次 npm install 并提交更新后的 package-lock.json。
静态托管
生成物是纯 HTML、CSS 与 JS,所以任意静态托管都能用:
| 宿主 | 需要设置 |
|---|---|
| EdgeOne Pages | install npm ci,build npm run docs:build,output docs/.vuepress/dist,Node 22.11.0(预装上限,原生绑定由守卫脚本补齐) |
| Vercel | 同样的命令,输出目录 docs/.vuepress/dist |
| Netlify | 同样的命令,发布目录 docs/.vuepress/dist |
| GitHub Pages | 跑 npm run docs:build,把 docs/.vuepress/dist 发布到 Pages 分支 |
| 任意 Web 服务器 | 把 docs/.vuepress/dist 拷到站点根目录 |
EdgeOne Makers:必须绕开它的构建环境
EdgeOne Makers 的 Git 集成构建会在它自己的容器里跑 installCommand 与 buildCommand。 这个容器预装的 Node 只有 14.21.3 / 16.20.2 / 18.20.4 / 20.18.0 / 22.11.0,最高到 22.11.0(见 edgeone.json 文档)。
而 Vite 8 通过 rolldown 编译,rolldown 的原生二进制以 optionalDependency 形式分发, 绑定包声明 engines.node: ^20.19.0 || >=22.12.0。于是 npm ci 在 Node 22.11.0 上会 静默跳过这个 optional 依赖 —— 只留一条 EBADENGINE 警告 —— 构建阶段随即抛:
Error: Cannot find module '../rolldown-binding.linux-x64-gnu.node'
Require stack:
- node_modules/rolldown/dist/shared/binding-BY0qR5iS.mjs这是「EdgeOne 部署一直失败」的典型形态:日志里看不出 enging 相关错误,只有一条模块找不到。
本仓库用两条互相独立的路径解决它。
路径一:在 CNB 里构建,再把产物推给 EdgeOne(推荐)
EdgeOne 预装的 Node 版本无法满足 Vite 8 的要求,那就不要用它构建。.cnb.yml 的 deploy-edgeone 流水线在 CNB 的 node:22.20 里跑构建,再用 EdgeOne CLI 把静态产物直传上去:
npx edgeone makers deploy docs/.vuepress/dist -n <项目名> -t $EDGEONE_API_TOKEN -e production需要在仓库密钥中配置:
| 密钥 | 必填 | 说明 |
|---|---|---|
EDGEONE_API_TOKEN | 是 | EdgeOne Makers → API Token |
EDGEONE_PROJECT_NAME | 否 | 项目名,默认 vuepress-theme-github |
没配 EDGEONE_API_TOKEN 时该阶段会打印提示并跳过,不会让流水线失败。
同时 .cnb.yml 里的 notify-edgeone 阶段会把 push 事件转发给 EdgeOne 的钩子地址。 CNB 原生不支持 Webhook,导入 CNB 仓库后如果不转发,EdgeOne 控制台里的 Git 集成 永远不会被触发。钩子地址由 EdgeOne 指定,不要修改。
路径二:让 EdgeOne 自己的构建也能跑通
如果你更希望用控制台的 Git 集成,本仓库也把这条路修通了。scripts/ensure-rolldown-binding.mjs 会在安装后 / 构建前检查原生绑定是否就位,缺失就按当前平台显式补装(直接安装可以绕开 optional 的 engines 跳过行为)。它同时挂在 postinstall 与 docs:build / build 上, 所以即使宿主用 --ignore-scripts 跳过 postinstall,构建前仍会被补上。
edgeone.json 已把 Node 固定到 EdgeOne 预装列表里的 22.11.0:
{
"$schema": "https://edgeone.ai/schema/edgeone.json",
"installCommand": "npm ci --no-audit --no-fund",
"buildCommand": "npm run docs:build",
"outputDirectory": "./docs/.vuepress/dist",
"nodeVersion": "22.11.0"
}不要写成 EdgeOne 未预装的版本(例如
22.20)。文档明确写了「使用其它版本可能导致部署失败」。
两条路径都验证过:在 Node 22.11.0 + npm 10.9.0 的容器里,npm ci && npm run docs:build 能从原来的 Cannot find module 变成构建成功、渲染 33 个页面。
会压坏静态构建的三件事
下面三种失败覆盖了绝大多数「VuePress 仓库接上宿主 Git 集成后构建失败」的情况。
1. 平台报 CNB not authorized
宿主读不到仓库。这是凭据问题,不是代码问题:私有 CNB 仓库需要用访问令牌把宿主连上 CNB (对仓库有读权限即可),或者把仓库设为公开。构建根本没真正开始,所以仓库里改不动。
2. 从 main 分支构建失败
请确认部署分支上确实有 package.json。如果宿主报 No package.json found 或 Could not read package.json,说明部署根目录指到了子目录(比如 docs),而不是仓库 根。根目录填仓库根。输出目录固定是 docs/.vuepress/dist。
3. 缺少 lib/ 导致的构建失败
docs/.vuepress/config.js 从 ../../lib/node/index.js 导入。lib/ 在 .gitignore 里,所以构建命令是裸 vuepress build docs 的宿主会因为找不到主题而失败,报 Could not resolve '../../lib/node/index.js'。
npm run docs:build 已经先构建了主题。只有把命令覆盖成 vuepress build docs 的宿主 才会踩到 —— 那里也用 npm run docs:build,或在前面加上 npm run build。
Node 版本
package.json 的 engines 声明 Node 22.11.0 或更新,CI 与推荐环境使用 node:22.20。
为什么下限是 22.11.0 而不是 VuePress 自己声明的 22.18.0:VuePress 2.0.0-rc.31 的 engines 只是一条策略下限,实际运行依赖的特性(如 import.meta.dirname)在更早的 Node 22 上就有。把下限降到 22.11.0 是为了覆盖 EdgeOne Makers 预装 Node 的上限 —— 否则平台会挑不到可用的运行时。Vite 8 与 @vueuse/core 在 22.11.0 上只会打印 EBADENGINE 警告,构建本身通过,原生绑定由 scripts/ensure-rolldown-binding.mjs 补齐。
在平台设置里指定 Node 版本,或在仓库里用 .nvmrc 固定:
22.20SPA fallback
站点是带预渲染 HTML 的单页应用。每个生成的路由都会写出真实文件(/guide/ 变成 guide/index.html,404.html 也会生成),所以通常不需要重写规则。如果你的宿主只提供 精确的文件路径,加一条指向 /404.html 的兜底,让未知 URL 渲染主题的 404 页面。
