npm、Yarn、pnpm 的对比

198 阅读4分钟

npm 和 Yarn、pnpm 的发展历程中,工具的功能、性能、以及社区支持不断演变。以下是各个版本及其对标关系的简要历史回顾:


npm 2.x (2014)

  • 发布时间: 2014 年

  • 特点:

    • 包的安装结构为嵌套依赖树(nested dependency tree)。

      • 这意味着依赖会嵌套安装到每个包的 node_modules 文件夹下,可能导致非常深的目录结构。
    • 容易出现最大路径长度问题(Windows 系统受限于文件路径长度)。

    • 没有 package-lock.json,因此无法保证安装一致性。

    • 性能较慢,尤其是在大型项目中。

  • 同时期竞争工具:

    • 没有出现 Yarn 和 pnpm。npm 仍然是唯一主流的包管理工具。

npm 3.x (2015)

  • 发布时间: 2015 年

  • 特点:

    • 重大变更:改用扁平化依赖树(flattened dependency tree)。

      • 将所有依赖尽可能提升到项目的 node_modules 根目录,避免深度嵌套。
      • 优点:解决了深度嵌套问题(Windows 文件路径限制)。
      • 缺点:可能导致依赖冲突(同一个依赖的多个版本需要手动解决)。
    • 更好的依赖解析和安装逻辑,但依然缺乏一致性保证。

    • 性能稍有提升,但依然比后来工具(如 Yarn、pnpm)要慢。

  • 同时期竞争工具:

    • Yarn 1.x:

      • 2016 年发布,是 Facebook 开发的新一代包管理工具。

      • 主要功能:

        • 引入了 yarn.lock 文件,保证依赖安装的一致性。
        • 离线缓存(offline cache)。
        • 并行化安装,大幅提升安装速度。
      • 对比 npm 3.x:

        • 性能显著优于 npm。
        • 更可靠的依赖锁定机制(npm 3.x 尚未有锁文件)。

npm 5.x (2017)

  • 发布时间: 2017 年

  • 特点:

    • 引入 package-lock.json:

      • 终于支持依赖安装的一致性,解决了 npm 2.x 和 3.x 的安装不确定性问题。
    • 离线缓存功能:

      • 在第一次安装后缓存包文件,后续无需重新下载。
    • 性能提升:

      • 比 npm 4.x 提升显著,安装速度接近 Yarn。
    • 默认使用 --save 标志(不再需要手动指定),自动将依赖写入 package.json

    • 扁平化依赖树更加优化。

  • 同时期竞争工具:

    • Yarn 1.x:

      • 在 2016 年发布后,继续迅速迭代,成为 npm 的最大竞争对手。
      • 提供了与 npm 类似的 CLI 和命令。
      • 性能依然优于 npm 5.x。
    • pnpm 1.x:

      • 2016 年发布,是一种基于软链接机制的包管理工具。

      • 主要特点:

        • 使用了内容寻址存储(Content Addressable Storage),将依赖保存在全局目录中,并通过符号链接到项目的 node_modules

        • 优点

          • 节省磁盘空间(相同版本的依赖只保存一份)。
          • 结构更加严谨,不允许幽灵依赖。
        • 对比 npm 5.x 和 Yarn:

          • 更快的安装速度。
          • 使用的磁盘空间更少。

npm 6.x (2018) 与对比

  • 发布时间: 2018 年

  • 特点:

    • 增强了安全功能,新增 npm audit 命令,用于检查依赖中的安全漏洞。
    • 进一步优化了 package-lock.json 和离线缓存功能。
    • 性能接近 Yarn,但仍然在某些场景下稍慢。
  • 同时期竞争工具:

    • Yarn 1.x:

      • 增加了更多工具功能,但性能和机制与之前变化不大。
    • pnpm 2.x:

      • 在性能上逐渐拉开差距。
      • pnpm 的严谨依赖管理机制(禁止幽灵依赖)受到更多社区关注,尤其是在大型项目中。

总结:npm、Yarn、pnpm 的对比

  1. npm:

    • npm 2.x 和 3.x: 曾经是唯一的选择,但缺点明显,性能和一致性问题较多。
    • npm 5.x 起: 引入锁文件、性能提升,逐渐追赶 Yarn。
    • 社区基础好,原生支持 Node.js。
  2. Yarn:

    • 出现于 2016 年,弥补了 npm 2.x 和 3.x 的不足。
    • 更快的安装速度、更可靠的锁文件机制,使得 Yarn 在一段时间内成为主流。
    • Yarn 1.x 在性能和一致性上全面领先 npm,但随着 npm 5.x 的改进,优势逐渐缩小。
  3. pnpm:

    • 2016 年发布,后起之秀。
    • 独特的软链接机制,使得依赖管理更加高效。
    • 性能和磁盘空间的利用率优于 npm 和 Yarn。
    • 更严格的依赖管理方式(禁止幽灵依赖)在 monorepo 项目中表现优异。

趋势:现阶段选型建议

  • 简单项目: npm >= 6.x 足够满足需求。
  • 性能和一致性要求高: 优先考虑 pnpm。
  • 团队已有 Yarn 基础: Yarn 仍是不错的选择,但可以逐步迁移到 pnpm。