01|这篇真正要先立住的,不是“后来大家有了更多包管理器”,而是 npm 赢下中央入口之后,真正被集中抱怨的已经不再是入口,而是入口后面的安装现实

到这一步,

npm 的中央地位其实已经很难动摇了。

大家默认:

  • 包发到 npm registry
  • 项目有 package.json
  • 依赖从那里找
  • JavaScript 世界的共享模块大都在那里流通

换句话说,

到这个阶段,

真正的问题已经不再是:

“有没有一个中央入口?”

而变成了:

“这个入口后面的安装、锁定、磁盘布局、依赖组织方式,到底是不是最合理的?”

这点特别重要。

因为很多人后来回头看 Yarnpnpm

容易把它们理解成:

“又来了两个新包管理器,要跟 npm 竞争天下。”

这话当然有一部分表面事实。

可如果只这么看,还是会把历史写浅。

因为 Yarnpnpm 真正要改写的,

很长时间里并不是“包去哪发、去哪找”。

它们真正想改写的,是:

  • 安装怎么做
  • 依赖树怎么锁
  • node_modules 怎么长
  • 工作区和 monorepo 怎么组织
  • 团队怎样得到更稳定、更快、更少惊吓的安装体验

所以第五篇真正的起点不是“新工具出现了”。

而是另一件更关键的事:

npm 先赢成了入口,随后大家才有空间开始认真抱怨:这个入口背后的现实,实在太需要重组。


02|为什么会突然想重组?因为 npm 世界到这时已经同时暴露出三种日常痛感:慢、不稳、乱

这一步要先把问题面摆清楚。

前几篇已经讲过:

  • 包越来越多
  • 小包文化把依赖链拉得越来越深
  • left-pad 让大家意识到传递性依赖很脆弱
  • semver 又只能部分兜底

这些东西叠到一起,

开发者对 npm 安装现实的体感就会越来越集中在三类抱怨上。

第一类是:

慢。

依赖越来越多,

安装越来越重,

网络、磁盘、CI 时间都开始成为真实成本。

第二类是:

不稳。

同一个 package.json

不同机器、不同时间、不同安装路径,

未必总能给你同样的结果和同样的目录状态。

第三类是:

乱。

尤其在更大的项目、workspace、monorepo 现实里,

你会越来越强烈地感觉到:

node_modules 的布局、hoisting 的副作用、幽灵依赖、磁盘浪费,

都已经不只是“小瑕疵”。

它们变成了持续消耗团队注意力的日常摩擦。

也就是说,

Yarnpnpm 的出场背景,

并不是因为社区突然厌倦 npm 这个名字。

而是因为 npm 赢下来的那套世界,已经把自己的摩擦集中到足以催生替代路线的程度。


03|Yarn 最早真正打中的,不是“换个命令”,而是它第一次把“安装必须可复现、可预测、可更快”讲成了 package manager 的头等公民

Yarn 当年出场时,

Meta 的官方说法非常直接:

他们在更大代码库、更大团队规模里,遇到了 consistency、security 和 performance 的问题。

这句话特别关键。

因为它说明 Yarn 最早不是以“我们也来搞个包管理器”的姿态出现的。

它更像是在说:

npm 时代默认存在的那些安装摩擦,已经在大项目里变成了系统性问题。

所以 Yarn 一上来打的点非常集中:

  • 更快
  • 更可靠
  • 更安全
  • 更一致

尤其是 lockfile 和 deterministic installs 这条线,

几乎就是直指 npm 现实里的日常痛点。

为什么这么有杀伤力?

因为它把一个很多团队已经隐隐感到不舒服、但没被说得那么清楚的问题,

一下说透了:

同样一份依赖声明,不应该因为安装顺序、环境差异或解析过程不同,就长出不一样的现实。

这点一旦被点明,

你就会发现 Yarn 当时真正卖的并不是“新命令体验”。

它卖的是:

团队终于可以更理直气壮地要求:安装结果应该更像基础设施,而不是更像碰运气。

这就是为什么 yarn.lock 会在当时那么快形成标志性存在。

因为它不只是一个文件。

它代表的是一种新姿态:

别只告诉我理论上的版本范围,给我把实际装下来的树钉死。


04|所以 Yarn 真正是在重新分配哪种权力?是在重新分配“谁来决定安装结果应该长什么样”的权力

这一步特别值得单独写。

因为很多人后来觉得 Yarn 和 npm 的差别只是“更快一点”。

其实远不止。

更深的差别在于:

Yarn 试图把安装结果的解释权,从“多数情况下差不多能用”推进到“应该可复现、可审核、可被团队共享”。

这意味着它在重新定义 package manager 的职责:

不只是能把包拉下来。

还要:

  • 把锁定信息写清楚
  • 把安装结果尽量固定
  • 把 checksums 纳入信任链
  • 让多人协作时的依赖状态更容易共享

这其实已经是一种更强的治理姿态。

也就是说,

Yarn 并不是说:

“npm registry 不要了。”

它更像是在说:

registry 还是那个 registry,但安装现实不能继续那么松散。

所以 Yarn 的历史角色,

其实不是“推翻中央仓库”。

而是:

在承认中央仓库已经成立之后,重新争夺安装秩序的定义权。


05|而 pnpm 再往前推了一步:它不只质疑安装结果该不该更稳定,还开始质疑 node_modules 这整个磁盘和依赖布局模型是不是本来就太浪费、太宽松

如果说 Yarn 最早强打的是:

  • 更快
  • 更可复现
  • 更可控

pnpm 的切口则更结构性。

它官方写得很明确:

  • 节省磁盘空间
  • 提升安装速度
  • 创建 non-flat node_modules

这三点放一起看,意思其实非常重。

因为它不是在说“我比 npm 再优化一点点”。

它是在说:

npm / Yarn Classic 那种把大量包铺进传统 node_modules、再靠 hoisting 把世界勉强抹平的模型,本身就有问题。

这条线的杀伤力非常强,

因为它同时命中两类旧痛点。

第一类是资源浪费:

  • 同样的包在很多项目里重复存很多份
  • 安装过程要做大量 I/O
  • 磁盘占用越来越夸张

第二类是依赖边界失真:

  • hoisting 让很多未声明依赖也能“碰巧可用”
  • 代码在本地能跑,不等于它的依赖声明是正确的
  • 团队在不知不觉里被幽灵依赖污染

pnpm 针对这两点给出的回答都很直接:

包内容应该尽可能共享存储,依赖访问也应该尽可能严格按声明来。

这比“装快一点”要更狠。

因为它等于在正面挑战:

npm 时代很多人早已习惯、甚至默认合理的安装与布局现实。


06|所以 pnpm 真正卖的,不只是快和省,而是一种更严格的依赖现实:你的包只能碰到它真正声明过的依赖

这点特别关键。

因为如果只把 pnpm 理解成“省磁盘的 npm 替代品”,

还是会把它写浅。

它更重的一层其实是:

strictness。

pnpm 官方文档明确强调,

传统 flattened node_modules 会让代码访问到自己并没有声明的依赖,

而 pnpm 更倾向于让只有真正声明过的依赖才出现在应该出现的位置。

这意味着什么?

意味着 pnpm 不是只在优化资源,

它还在重新纠正一个 npm 时代被长期容忍的问题:

依赖图和运行时现实不一致。

这很重要。

因为工程上很多麻烦,

并不是来自“包太多”本身。

而是来自:

你以为你依赖的是 A,

可实际上你还偷偷靠着 hoisting 和历史安装结果,

摸到了 B、C、D。

这种事情在小项目里也许只是脏。

可在大项目和 monorepo 里,

它会直接变成:

  • 难以迁移
  • 难以重构
  • 难以验证
  • 难以解释为什么别人机器上会坏

所以 pnpm 的历史位置很有意思。

它不是简单说:

“我来让你更快。”

它更像是在说:

我来让你的依赖关系更接近它自己在声明层面声称的样子。


07|这也是为什么 Yarn 和 pnpm 虽然路线不同,但本质上都不是在推翻 npm 的中心,而是在 npm 已经确立中心之后,对“安装秩序”发起内部改造

这一步是第五篇最该立住的总判断。

因为 Yarnpnpm 表面看不太一样:

  • Yarn 早期更强调 consistency、speed、security、lockfile
  • pnpm 更强调 content-addressable store、strictness、non-flat node_modules

可如果把它们放在同一条大线上看,

你会发现两者真正共同的地方其实很明显:

它们都默认 npm registry 仍然是世界中心,但都不再愿意无条件接受 npm 时代那套默认安装现实。

也就是说,

它们争的不是:

“包应该去哪发。”

它们争的是:

  • 包装到本地时该怎么落地
  • 依赖树该怎样被锁定
  • 工作区该怎样组织
  • 磁盘、速度和正确性该怎样平衡

这就说明,

到这个阶段 npm 江湖真正进入的新阶段已经不是“入口之争”。

而是:

入口已定之后,秩序重组开始向安装层、锁定层和目录层下沉。

这也是为什么 Yarn / pnpm 看似是工具分流,

本质上更像一场内部宪法修订。


08|为什么 npm 真正赢下来之后,大家才开始集体质疑安装现实

把前面几层叠一起看,第五篇最重要的判断可以压成一句:

Yarn 和 pnpm 之所以会长出来,不是因为 npm 没赢,而正是因为 npm 已经赢了,大家才终于能把矛头集中对准“赢下来之后的安装现实到底合不合理”。

这句话里有几层意思。

第一,Yarn / pnpm 不是在争中央仓库名义。

它们大多仍建立在 npm registry 这套世界之上。

第二,Yarn 最早打中的,是大团队对 consistency、lockfile、deterministic installs 和安装速度的强烈需求。

第三,pnpm 则把问题再推进到更深一层:

它开始挑战传统 node_modules、磁盘复制和幽灵依赖这整套旧现实。

第四,两者虽然技术路线不同,但都属于 npm 中心秩序建立之后,对安装层秩序的内部重写。

所以理解 npm 的第五步,

最不该只记住:

“后来又多了两个包管理器。”

更该记住的是:

当中央仓库已经成为现实,真正的下一场战争,往往就会从“包去哪找”转向“包落到本地之后,整个依赖现实到底该长什么样”。


09|Yarn 和 pnpm 把 npm 之争推进到了安装治理

npm 江湖 的第五篇,最值得记住的,不是“Yarn 更快”或“pnpm 更省空间”这种表层选型结论。

更值得记住的是:

它们的出现标志着 npm 世界的矛盾已经从“能不能共享代码”推进到了“共享之后,安装现实、锁定现实和依赖边界现实到底该怎样治理”这一层。

也正因此,

到这时大家担心的,

已经不再只是复用会不会太碎、版本号会不会失灵。

更大的问题会继续往前顶:

  • 这套生态到底可不可信
  • 发布来源能不能验证
  • 账户和 token 会不会被接管
  • 整条供应链里哪一环最容易被污染

这也就是最后一篇要接上的地方。

因为当 npm 已经不仅是包分发入口,

而是整个现代前端的基础设施时,

最终压上来的那条线一定会是:

安全与供应链。


编者注(事实核对):文中关于 Yarn 出场时的核心诉求,主要依据 Meta 官方发布的《Yarn: A new package manager for JavaScript》,其中明确把 consistencysecurityperformance 列为 Yarn 诞生背景,并强调 lockfile、deterministic install algorithm、checksums、global cache 与 parallelization 等能力。关于 Yarn 当前官方定位,主要依据 Yarn 官方文档 Introduction 与首页说明,其中将 Yarn 的重点概括为 speedcorrectnesssecuritydeveloper experience,并强调 workspaces、offline cache、hardened mode 等特性。关于 pnpm 的动机,主要依据 pnpm 官方文档 MotivationSymlinked node_modules structure,其中明确说明 content-addressable store 如何节省磁盘、提升速度,以及 non-flat / symlinked node_modules 如何减少 phantom dependencies。正文将这些线索综合概括为“Yarn 和 pnpm 都是在 npm 已经赢下入口之后,对安装秩序发起内部改造”,属于对官方动机、工程现实与生态阶段变化的综合判断。


关键人物速览

  • Sebastian McKenzie:Yarn 早期关键推动者之一。理解 Yarn 为什么会把 deterministic installs 和 lockfile 体验推到那么高的位置,绕不开他。
  • Zoltan Kochan:pnpm 的核心作者。理解 pnpm 为什么会从磁盘模型、依赖布局和 strictness 上重写安装现实,绕不开他。
  • James Kyle:Yarn 早期重要推动者之一。理解 lockfile、团队一致性和 monorepo 体验为什么会在 Yarn 世界里变成中心议题,绕不开他。

参考与延伸阅读

  1. Yarn: A new package manager for JavaScript
    https://engineering.fb.com/2016/10/11/web/yarn-a-new-package-manager-for-javascript/

  2. Introduction | Yarn
    https://yarnpkg.com/getting-started/

  3. Home page | Yarn
    https://yarnpkg.org/

  4. Lockfiles should be committed on all projects | Yarn Blog
    https://classic.yarnpkg.com/blog/2016/11/24/lockfiles-for-all/

  5. Yarn determinism | Yarn Blog
    https://classic.yarnpkg.com/blog/2017/05/31/determinism/

  6. Motivation | pnpm
    https://pnpm.io/motivation

  7. Symlinked node_modules structure | pnpm
    https://pnpm.io/symlinked-node-modules-structure

  8. Fast, disk space efficient package manager | pnpm
    https://pnpm.io/


下篇预告:安全与供应链为什么会越来越重,因为当 npm 已经成为公共基础设施,大家最终害怕的就不再只是装包得快不快,而是这条流通链到底还能不能信。