建议固定 pnpm 版本(packageManager + corepack)并提交锁文件:pnpm 10/11 破坏性变更导致 CI 随机失败

Author: syschanCreated Aug 27, 2026Updated Aug 27, 2026

问题描述

web/Dockerfile 当前用 npm i -g pnpm(安装 latest),而 pnpm 的破坏性变更会让构建"随机"失败:

  • pnpm 10(2025-01 发布):默认不执行依赖的 build/postinstall 脚本(安全改进),仅打印 Warning
  • pnpm 11(2026-04 发布,当前 latest 11.24.0):strictDepBuilds 默认开启,pnpm install 遇到未获批的 build 脚本直接报 ERR_PNPM_IGNORED_BUILDS 失败

本仓库依赖树含多个带 build 脚本的包(@vueuse/corevue-demi@parcel/watcher@logicflow/core@vue-office/docx/excel/pdfcore-js-purees5-ext 等),因此:

  • 构建装到 pnpm 10.x → 仅警告 → 通过
  • 构建装到 pnpm 11.x → 直接失败

实测案例:同一份源码、同一 Dockerfile,昨天镜像源 latest 为 pnpm 10.34.5 → 构建通过(日志:Done in 32.1s using pnpm v10.34.5,Ignored build scripts 仅 Warning);今天镜像源把 latest 同步到 11.24.0 → ERR_PNPM_IGNORED_BUILDS 构建失败。代码一行没改,全靠"镜像源 latest 标签"决定成败——这是构建不可复现的典型例子。

官方现状

官方 Dockerfile 使用 corepack enable(比 npm i -g pnpm 稳),但 web/package.json 没有 packageManager 字段,corepack 只能回退到内置默认 pnpm 版本(Node 20 自带 corepack 默认约 9.x),属于"隐形未固定":

  • 目前碰巧安全(9.x 无此行为)
  • 但默认值随 Node 基础镜像升级而漂移——Node 24 的 corepack 默认 pnpm 已是 11.24.0,官方镜像一旦升级 Node 就会立刻踩坑

建议

  1. web/package.json 增加 packageManager 字段显式固定 pnpm 版本,例如:
    • "packageManager": "[email protected]"(回到警告行为,改动最小);或
    • "packageManager": "[email protected]" + allowBuilds 白名单(注意 pnpm 11 已移除 onlyBuiltDependencies,改为 pnpm-workspace.yaml 中的 allowBuilds;推荐,符合"默认拒绝 + 显式放行"的安全实践)
  2. Dockerfile 配合 corepack 按 packageManager 解析版本(corepack use / corepack prepare ... --activate),并加 RUN pnpm --version 让构建日志可观测
  3. 提交 pnpm-lock.yaml(当前被 .gitignore 忽略),CI 使用 pnpm install --frozen-lockfile,彻底杜绝依赖/工具链版本漂移(也是供应链安全的基本要求)
  4. 若担心依赖脚本风险,建议用白名单而非 --ignore-scripts(会静默跳过 vue-demi 等必要脚本)

参考

该问题为生态级:任何用 pnpm@latest 构建本仓库源码的部署都会在 pnpm 11 时代遇到,非个例。

Source: flipped-aurora/gin-vue-admin