91 lines
3.8 KiB
Markdown
91 lines
3.8 KiB
Markdown
# npm
|
||
  2010年随Node.js发布的npm,首次为JavaScript引入了标准的包管理系统。其核心创新是**package.json文件**,通过语义化版本规范定义了依赖声明标准。这一设计解决了手动管理依赖时的版本混乱问题,为模块化开发提供了基础设施。
|
||
|
||
## 第一阶段:嵌套依赖架构
|
||
  早期版本采用树状嵌套的依赖结构。每个包将其依赖安装在自身的node_modules目录中,形成深层嵌套。这种设计保证了依赖隔离,但导致了几个严重问题:
|
||
- 路径深度问题:依赖树深度可达十几层,触发Windows 260字符路径限制
|
||
- 空间极度浪费:相同包在不同层级重复安装,项目体积指数级膨胀
|
||
- 安装性能低下:大量递归操作导致I/O效率极低
|
||
|
||
## 第二阶段:扁平化依赖重构
|
||
  2015年发布的npm v3引入扁平化依赖安装策略。该方案将**可共享的依赖提升到顶层node_modules**,减少嵌套深度。
|
||
  主要解决方案为:
|
||
- 依赖提升算法:将兼容版本的依赖包提升至顶层
|
||
- 冲突处理:版本冲突时,低版本保持嵌套结构
|
||
- 确定性牺牲:提升顺序影响最终结构
|
||
|
||
  但同时也引入了新问题:
|
||
- 幻影依赖:未声明但被提升的包意外可用
|
||
- 依赖不确定性:相同package.json产生不同目录结构
|
||
- 模块解析复杂化:Node.js模块解析算法与扁平结构不匹配
|
||
|
||
# yarn
|
||
  2016年发布的Yarn针对npm核心痛点提出了系统性解决方案:
|
||
- 确定性版本锁定:yarn.lock文件记录精确版本和依赖树
|
||
- 并行下载优化:多线程并发下载提升网络利用率
|
||
- 离线缓存机制:全局缓存支持离线安装
|
||
- 完整性校验:checksum验证确保包完整性
|
||
|
||
  Yarn的成功迫使npm进行重大改进。npm v5版本借鉴了Yarn的核心设计,增加了package-lock.json和缓存优化,形成了技术竞争的良性循环。
|
||
|
||
# pnpm
|
||
  2017年发布的pnpm从存储层面重新设计了包管理模型。其核心是**基于内容寻址的全局存储与符号链接架构**。
|
||
  实现原理:
|
||
- 内容可寻址存储:包按内容哈希存储,全局唯一
|
||
- 硬链接复用:相同包文件在所有项目间共享
|
||
- 符号链接树:通过软链接构建符合Node.js解析规则的依赖树
|
||
- 严格依赖隔离:每个包只能访问其声明的依赖
|
||
|
||
  npm/yarn的node_modules目录:
|
||
```cmd
|
||
项目A: node_modules/lodash@4.17.21
|
||
项目B: node_modules/lodash@4.17.21 # 重复存储
|
||
项目C: node_modules/lodash@4.17.21 # 重复存储
|
||
```
|
||
|
||
  pnpm的node_modules目录:
|
||
```cmd
|
||
全局存储: .pnpm-store/lodash@4.17.21
|
||
项目A: 硬链接 → 全局存储
|
||
项目B: 硬链接 → 全局存储
|
||
项目C: 硬链接 → 全局存储
|
||
```
|
||
|
||
  npm/Yarn采用扁平化结构,包可访问非声明依赖,pnpm采用符号链接嵌套结构,包仅可访问声明依赖。
|
||
  pnpm的符号链接架构在Monorepo场景中表现优异。跨包依赖通过本地文件系统链接实现,避免了重复安装。Workspaces功能通过优化符号链接策略,确保开发环境与生产环境一致性。
|
||
|
||
## 简单使用
|
||
```cmd
|
||
# 通过 npm 安装
|
||
npm install -g pnpm
|
||
|
||
# 检查版本
|
||
pnpm --version
|
||
|
||
# 安装所有依赖(根据 package.json)
|
||
pnpm install
|
||
|
||
# 安装生产依赖
|
||
pnpm add <package-name>
|
||
|
||
# 安装开发依赖
|
||
pnpm add -D <package-name>
|
||
|
||
# 移除依赖
|
||
pnpm remove <package-name>
|
||
|
||
# 查看所有配置
|
||
pnpm config list
|
||
|
||
# 设置存储路径
|
||
pnpm config set store-dir ~/.pnpm-store
|
||
|
||
# 使用淘宝镜像
|
||
pnpm config set registry https://registry.npmmirror.com/
|
||
```
|
||
|
||
::: tip
|
||
npm确立了基本范式,Yarn解决了确定性问题,pnpm重构了存储模型
|
||
:::
|
||
|