跳转至

2026-07-31

今日主题

  • pnpm Workspace 与包管理边界

新增认知

pnpm Workspace 与包管理边界

  • 工作区分层:Workspace 是 npm、pnpm、Yarn 等包管理器共同采用的 monorepo 抽象,不是 Node.js 的统一标准;
    各工具解决的都是多 package 协同问题,但成员声明和命令语义属于各自实现。
    npm 通过根 package.json 的 workspaces 字段声明成员,
    pnpm 则以 pnpm-workspace.yaml 定义根与目录 glob,因此配置文件不能跨包管理器直接互认。

  • 根包是聚合器:pnpm monorepo 中,pnpm-workspace.yaml 回答“哪些目录是成员”,
    根 package.json 回答“仓库如何安装、测试、构建和约束工具版本”。两者合起来类似 Maven aggregator/parent POM,
    但 npm 子包不会继承根包的 version、dependencies 或 scripts;每个可发布包仍须维护完整 manifest。

  • 私有不是内网:package.json 的 private: true 是当前 package 的发布保险,npm 会拒绝发布它;
    它既不表示“发布成公司内部可见的私有包”,也不会阻止 workspace 下未标记 private 的子包发布。内部 npm 包仍是正常发布,
    只是通过 publishConfig 或 .npmrc 把 registry 指向公司仓库。

  • 仓库与客户端分离:npm registry 是软件包存储协议与服务,npm、pnpm 是可访问该 registry 的不同客户端。
    因此使用 npm.poizon.com 不要求使用 npm CLI;脚手架可以由 npm create 启动,而脚手架仓库和生成项目继续统一使用 pnpm,
    两者并不冲突。

  • 绑定源于工程约定:React、Vite 和普通 semver 依赖本身不绑定 pnpm,
    但 packageManager 字段、pnpm-lock.yaml、脚本中的 pnpm 调用、CLI 自动执行 pnpm install,
    以及 AGENTS.md 约束会把生成项目固定到 pnpm。这种绑定是为了依赖可复现、CI 一致和模板维护收敛,而非框架的技术限制;若要支持自由选择包管理器,
    必须同时参数化安装命令、脚本、锁文件和文档。

  • 版本需要显式同步:npm package 的自身版本不能像 Maven 子模块那样从根包继承。
    多个发布包可以使用 pnpm fixed versioning 或小型版本脚本保持同一发布版本,
    但模板中不属于 workspace 的依赖版本仍需额外更新和校验;第三方依赖版本统一则是另一问题,可使用 pnpm catalog,
    不能与发布包版本治理混为一谈。