npm 与 Yarn 在依赖管理上有什么本质区别?
1. 安装策略与目录结构
- npm 采用扁平化(hoisted)的 node_modules 结构,将依赖尽可能提升到顶层
- Yarn Classic(1.x)与 npm 类似,使用传统的 node_modules 布局
- Yarn Berry(v4)默认使用 Plug'n'Play(PnP)模式,完全消除 node_modules,通过 .pnp.cjs 文件映射导入路径
2. 依赖解析与严格性
- npm 允许"幽灵依赖"(phantom dependencies):代码可以导入未在 package.json 中声明但被传递安装的包
- Yarn PnP 通过 Node.js 加载器强制声明的依赖边界,未声明的导入会被拒绝
- pnpm 使用符号链接与内容寻址存储实现严格隔离,防止幽灵依赖
3. 生态定位与适用场景
- npm 随 Node.js 自带,零配置,适合初学者与简单项目
- Yarn 由 Facebook 于 2016 年创建,在 monorepo 场景下提供 constraints、workspace profiles、catalog 协议等高级功能
- pnpm 以磁盘效率(硬链接共享)与安装速度见长,逐渐成为大型项目的首选