pnpm npm yarn 对比

223 阅读3分钟

pnpm

pnpm 如何用硬链接

  • pnpm 在本地创建一个全局的 store(存储区, .pnpm-store),所有安装的包版本都集中存放在这里,只存一份,可以通过pnpm store path 查看路径,du -sh 查看大小
  • 当你在项目中安装依赖时,pnpm 不复制这些包到项目的 node_modules,而是用**硬链接(hard link)**把全局存储区的文件“映射”到项目目录下。
  • 硬链接让项目中依赖的文件其实指向的是同一份磁盘数据,没有重复占用空间。
  • 同时,pnpm 通过特殊的文件结构,保证模块解析正常,不会因为硬链接造成模块冲突。

pnpm 硬链接的优势

  1. 节省磁盘空间
    多个项目共用同一份依赖文件,不用每个项目都复制一份。
  2. 安装速度快
    不用重复复制文件,只需要创建硬链接,速度更快。
  3. 一致性强
    由于指向同一个存储,避免了包版本和内容不一致问题。

yarn

相较于npm安装速度更快,lock文件结构相对于npm更加扁平

npm

兼容性强,安装速度慢,lock文件为树级结构,比较清晰

对比

特性npmYarnpnpm
发布年份201020162016
安装速度中等,早期串行,后续改进快,默认并行安装更快,基于硬链接节省时间
依赖存储复制依赖到 node_modules复制依赖到 node_modules使用硬链接到全局缓存目录
磁盘空间利用低,重复存储依赖低,复制依赖高,依赖通过硬链接共享
锁文件名package-lock.jsonyarn.lockpnpm-lock.yaml
锁文件格式JSON自定义类似 INI 格式YAML
工作区(Monorepo)支持npm 7+ 支持,较新原生支持 Workspaces原生支持 Workspaces
离线缓存有缓存,支持离线安装有完善缓存,支持离线安装有缓存,依赖共享,支持离线
依赖扁平化逐步改进,传统深层依赖结构扁平化做得较好依赖隔离但结构优化,避免冲突
新特性逐步加入新功能Plug’n’Play(PnP)无 node_modules基于硬链接,快速且节省空间
社区支持官方,最广泛Facebook 支持,社区活跃新兴,成长快,受欢迎
命令行体验标准,逐渐改进丰富,交互友好类似 npm,兼容性好

bash脚本测试

# !/bin/bash

echo "$1 ⚙️ 正在初始化测试项目..."
rm -rf test-project
mkdir test-project && cd test-project

echo "📦 初始化 package.json"
if [ "$1" = "pnpm" ]; then
pnpm init  > /dev/null
elif [ "$1" = "npm" ]; then
npm init -y > /dev/null
elif [ "$1" = "npm" ]; then
yarn init -y> /dev/null
fi
echo "📦 安装依赖:"
package="react react-dom react-router-dom redux @reduxjs/toolkit styled-components axios webpack webpack-cli  @babel/core @babel/preset-env eslint prettier jest ts-jest @testing-library/react"

start_time=$(date +%s)
if [ "$1" = "pnpm" ]; then
pnpm add $package > /dev/null
echo "📁 pnpm 全局共享依赖 体积如下:"
du -sh $(pnpm store path)
elif [ "$1" = "npm" ]; then
npm install $package > /dev/null
elif [ "$1" = "yarn" ]; then
yarn add $package > /dev/null
fi
end_time=$(date +%s)

echo "✅ 安装完成,用时 $((end_time - start_time)) 秒"

echo "📁 node_modules 体积如下:"

du -sh node_modules

# ncdu 可以通过ncdu 查看硬连接详情 ncdu . 

测试后结果符合预期

安装速度 pnpm > yarn >> npm

占用空间 npm > yarn >> pnpm