简介pnpm是一个快速且节省磁盘空间的包管理工具。pnpm使用内容寻址文件系统将所有模块文件存储在磁盘上项目地址https://github.com/pnpm/pnpm使用npm安装npminstall-gpnpm使用Homebrew如果你已经安装了Homebrew包管理器,那么你可以使用安装pnpm的命令如下:brewinstallpnpmCompatibility下图列出了之前的pnpm版本和对应支持的Node.js版本。installnpmipnpmaddnpmrunpnpm速度快。与npm/yarn相比,两个常用的包管理工具的性能有了很大的提升。下图为官方benchmark数据,以节省磁盘空间。pnpm内部使用内容寻址的文件系统来存储磁盘1.使用npm/yarn时,如果你有100个项目,所有项目都有相同的依赖包,那么你需要在硬盘上保存100份相同的依赖包,但是pnpm这部分代码只会写在一处,后面直接使用硬链接,不会额外占用磁盘空间。2、当依赖包需要更新到新版本,且新版本中只有一个文件被修改时。pnpm不会重写101个文件,而是保留原来100个文件的硬链接,只将新添加的文件写入存储。依赖管理pnpm采用硬链接(hardlink)和符号链接(symlinks)来创建依赖的嵌套结构假设foo@1.0.0依赖bar@1.0.0,pnmp会将这两个包硬链接到node_modules:node_modules└──.pnpm├──bar@1.0.0│└──node_modules│└──bar->/bar│├──index.js│└──package.json└──foo@1.0.0└──node_modules└──foo->/foo├──index.js└──package.json一旦所有包都硬链接到node_modules中,符号链接用于构建嵌套依赖关系图正如你可能已经注意到,这两个包都硬链接到node_modules文件夹(foo@1.0.0/node_modules/foo)的子文件夹中。这是为了:允许包导入自身。foo可以require('foo/package.json')或import*aspackagefrom"foo/package.json"以避免循环符号链接。包的依赖放在依赖包所在的文件夹中。对于Node.js,依赖项是放在包的node_modules中还是放在某个父目录的node-modules中没有区别。接下来,安装符号链接依赖项。bar符号链接到foo@1.0.0/node_modules文件夹:node_modules└──.pnpm├──bar@1.0.0│└──node_modules│└──bar->/bar└──foo@1.0.0└──node_modules├──foo->/foo└──bar->../../bar@1.0.0/node_modules/bar接下来处理直接依赖。foo将符号链接到node_modules根文件夹,因为foo是项目的依赖项:node_modules├──foo->./.pnpm/foo@1.0.0/node_modules/foo└──.pnpm├──bar@1.0.0│└──node_modules│└──bar->/bar└──foo@1.0.0└──node_modules├──foo->/foo└──bar->。./../bar@1.0.0/node_modules/bar这是一个非常简单的例子。但是,无论依赖项的数量和依赖图的深度如何,布局都会保持这种结构。如果此时添加qar@2.0.0作为bar和foo的依赖:node_modules├──foo->./.pnpm/foo@1.0.0/node_modules/foo└──.pnpm├──bar@1.0.0│└──node_modules│├──bar->/bar│└──qar->../../qar@2.0.0/node_modules/qar├──foo@1.0.0│└──node_modules│├──foo->/foo│├──bar->../../bar@1.0.0/node_modules/bar│└──qar->../../qar@2.0.0/node_modules/qar└──qar@2.0.0└──node_modules└──qar->/qar正如你所看到的,尽管图表现在更深了(foo>bar>qar),文件系统中的目录深度保持不变。这种布局乍一看可能很奇怪,但它实际上完全兼容Node的模块解析算法!node_modules根目录中的包只是一个符号链接。require('foo')将执行node_modules/.pnpm/foo@1.0.0/node_modules/foo/indexjs(此处为硬链接)中的文件,而不是node_modules/foo/index.js中的文件。严格性这种布局的一大好处是只有真正处于依赖关系中的包才可以访问。如果使用扁平的node_modules结构,程序可以访问一些不在package.json依赖项中的包。这避免了一些愚蠢的错误