包管理器挖掘🪦

发布: (2025年12月13日 GMT+8 17:19)
4 min read
原文: Dev.to

Source: Dev.to

Cover image for 패키지 매니저 파묘🪦

包管理器的历史

npm 的问题点

  • 重复的依赖下载
    依赖会依赖其他依赖,层层递进。即使包名和版本相同,npm v1、v2 仍会重复下载,导致安装时间变长。

  • 安装方式导致的请求瀑布(request waterfall)
    由于顺序解析并下载依赖,无法并行下载。
    1️⃣ 依赖 1 安装 → 检查 package.json → 依赖 2 安装 → …
    这一过程按顺序进行,使得安装时间延长。

  • 无法锁定包版本
    没有 lockfile,各开发者使用的版本各不相同。package.json 只固定 ^(主版本)或 ~(次版本),所有人都会使用不同的版本进行开发和发布,导致问题难以复现。

read package1/package.json
└─ find package2
   └─ download package2
      └─ read package2/package.json
         └─ find package3
            └─ download package3

read package.json → find package → download package 按顺序发生,使得 npm install 时间变长。

解决下载瓶颈的 yarn classic

  • 依赖缓存
    当相同的包名·版本出现重复时,使用缓存来缩短下载时间。重复的包会通过提升(hoisting)移动到上层目录。

  • 先绘制依赖图再并行下载

fetch package metadata from registry (JSON)
→ read dependencies from metadata
→ resolve versions (lockfile 优先)
→ 完成整个 dependency graph
Download packages in parallel
  • 通过 lockfile 锁定包版本
    lockfile 中写明到补丁版本,所有人都在相同的依赖版本上进行开发、CI、部署,错误复现难度大幅降低。

yarn classic 的问题点

隐式依赖导致的项目依赖崩溃

Node.js 在寻找模块时会从当前目录向上查找 /node_modules/package。由于提升,未在 package.json 中声明的包会被放到最上层的 /node_modules,从而可以被 import,这类依赖被称为 phantom dependencies(幽灵依赖)。

磁盘 I/O 导致的模块解析速度下降

大量目录扫描产生磁盘 I/O,导致 yarn devyarn build 时开发服务器启动和构建时间变慢。

import lodash
→ filesystem walk-up
→ /node_modules/lodash 在吗? OK

解决隐式依赖的 yarn berry

用映射表文件指明位置

.pnp.cjs 文件中声明每个依赖的路径,并覆盖 Node.js 的 require() 行为,使其参考 .pnp.cjs 来寻找依赖路径,从而阻断隐式依赖的产生。

用单个文件处理所有逻辑,避免大量磁盘 I/O

因为 require() 被覆盖,重复的磁盘 I/O 消失。

import lodash
→ .pnp.cjs 加载
→ 检查当前包的 dependency graph
→ 在 package.json 中声明了吗?
   ❌ No → 立即报错
Back to Blog

相关文章

阅读更多 »

实验性 Hono auth npm 包

我正在构建的东西:我正在创建一个 auth package,开发者可以将其直接放入他们的应用中,而无需编写常规的登录、注册、JWT、电子邮件验证等样板代码。

到底什么是构建系统?

宏观视角 在高层次上,build systems 是提供一种定义和执行从输入数据到输出的一系列转换的工具或库。