一文带你学会pnpm

您所在的位置:网站首页 宝宝宴策划方案价格表 一文带你学会pnpm

一文带你学会pnpm

#一文带你学会pnpm| 来源: 网络整理| 查看: 265

pnpm.png 作为一名前端程序媛👨🏻‍💻,对npm和yarn这两个包管理器一定不陌生,那么你听说过pnpm么?它到底是个什么东西?和npm还有yarn有什么区别,又有什么作用呢?本文就将解决以下这几个问题:

pnpm是什么?有什么作用 pnpm有什么优势和特点 pnpm与npm和yarn有什么不同? pnpm如何安装和使用 pnpm是什么

快速的,节省磁盘空间的包管理工具

Fast, disk space efficient package manager

通过pnpm的简介我们可以看出来它实际上就是一个包管理工具,作用是跟npm和yarn一样的呢。那既然功能是一样的为什么又要出现一个pnpm呢?通过官方的文档我们可以看出来它的优势在于:

包安装速度极快 磁盘空间利用效率高 pnpm有什么优势和特点

我们上面提到了pnpm的优势在于包安装速度极快和磁盘空间利用效率高。

包安装速度极快

比传统方案安装包的速度快了两倍,以下是官方给出的benchmarks(对比了npm, pnpm, Yarn Classic, and Yarn PnP),在多种常见情况下,执行install的速度比较

image.png

为什么pnpm要比其他的包处理器要快呢?

主要得益于它的包管理机制,实现了节约磁盘空间并提升安装速度(也就是第二个优势)

磁盘空间利用效率高

pnpm 的 node_modules 布局使用符号链接来创建依赖项的嵌套结构。node_modules 中每个包的每个文件都是来自内容可寻址存储的硬链接。

那么为什么说pnpm这种基于内容寻址的方式对磁盘空间利用效率比较高呢

不会重复安装同一个包。使用npm/yarn 的时候,如果100个包依赖express ,那么就可能安装了100次express ,磁盘中就有100个地方写入了这部分代码。但是pnpm会只在一个地方写入这部分代码,后面使用会直接使用硬链接

image.png

即使一个包的不同版本,pnpm 也会极大程度地复用之前版本的代码。举个例子,比如 express4.18.1 和epxress5.0.0-beta.1的两个版本升级对比,epxress5.0.0-beta.1只是重新下载了19个新的更新的包。

image.png

pnpm与npm和yarn有什么不同?

pnpm与npm和yarn的不同点主要是从包的依赖管理方面来说明。

npm2的依赖管理

npm2生成的依赖管理比较的简单直接,会按照安装包的依赖树形结构直接填充在本地的目录结构下:

比如express和koa他们会同时依赖accepts,那么在install之后生成的node_modules就会是如下结构:

image.png

npm2的这种方式的优点就是比较的直观,但是呢缺点也是显而易见的就是

层级依赖过深 相同包的相同版本会多次被下载,利用率低,占用磁盘空间大 npm3/yarn的依赖管理

针对npm2的两个缺点呢,npm3做了个改变,不再使用嵌套的结构了,而是讲依赖进行打平,这样就能解决层级依赖深和包的利用率的问题,那么上面的依赖关系就会变成下面这个样子:

image.png

在文件里看就是下面的这个样子(为了方便观看,把其他依稀依赖包手动删除了😁):

image.png

我们可以看出,[email protected][email protected]引用了accepts的版本是一样的,这样才会被平铺在node_modules下,那如果引用的包的版本不一样又是什么样的情况呢?就像debug,http-errors 、statuses等这几个包

[email protected]引入的是:[email protected][email protected][email protected] [email protected]引入的是:[email protected][email protected][email protected]

此时,在node_modules结构是下面这个样子:

image.png

image.png

至于为什么说[email protected]的依赖包会在根目录的node_modules下呢,这是npm自己的一个规则,具体可以看一下与你项目相关的npm知识总结

npm3的这种平铺方式确实是解决了层级依赖深和包的利用率的问题,但是也引入了其他的问题:

对没有手动引入的包,例如[email protected]依赖的cookie,项目中手动引入,但是依然可以使用,这样就造成了如果哪天express改变了策略不在使用cookie,而我们的项目中又使用了cookie,这样就会导致项目无法启动 虽然npm是共享了相同版本的依赖,但是如果版本不同,npm还是会完整的下载两个不同的版本,这样也会有依赖的冗余 pnpm的依赖

pnpm为了解决npm3带来的一些问题呢,采用了另外一种方式来管理依赖:pnpm 的 node_modules 布局使用符号链接来创建依赖项的嵌套结构管。

node_modules 中.pnpm下每个包的每个文件都是来自内容可寻址存储的硬链接。

这是 node_modules 中的唯一的“真实”文件。 一旦所有包都硬链接到 node_modules,就会创建符号链接来构建嵌套的依赖关系图结构。

我们用pnpm安装一下[email protected][email protected],生成的目录如下所示:

image.png

在node_modules中的依赖只有在package.json中手动引入的依赖express和koa,细心的你会发现这两个文件后面有一个箭头,而这个箭头就是pnpm使用的软连接的方式指向了.pnpm文件真正的文件:

image.png

这些文件会在内存中统一存储,如果有依赖不同版本的时候,pnpm也只会下载不同版本中不同的内容。对比

image.png

小课堂:硬链接和软连接的区别 linux下有两种链接,一种是硬链接(Hard Link),另一种是符号链接(Symbolic Link),也可以称之为软连接

硬链接:只能引用同一文件系统中的文件。它引用的是文件在文件系统中的物理索引(inode)。当移动或者删除原始文件时,硬链接不会被破坏,因为它所引用的是文件的物理数据而不是文件在文件结构中的位置。硬链接记录的是目标的inode。同一文件的不同硬链接文件相当于该文件的多个不同文件名,即多个不同访问路径,他们的inode都是一样的。不可以为目录创建软连接。 符号链接:和原文件不是同一个文件,符号链接会有自己的inode,它所引用的是原文件的path,当原文件被移动或删除的时候,符号链接的文件就不可以。例如windows中的快捷方式。也可以为目录创建软连接。 如何建立硬链接和软连接呢 可以使用ln命令来创建 ln 原文件名 硬链接文件名, 例如: ln file hardfile,就是创建了file文件的硬链接文件hardfile ln -s 原文件名 硬链接文件名,例如: ln -s file softfile,就是创建了file文件的硬链接文件softfile 在系统中查看操作一遍(执行以下命令) touch file && echo 'thisi is init file' > file ln file hardfile ln -s file softfile ln -ls

image.png 可以看到hardfile和file的inode是一样的(最左侧的33038778),而softfile是有了一个自己的inode 此时如果删除file文件 rm file,再去查看hardfile和softfile看一下有什么变化

cat hardfile cat softfile

此时会发现,hardfile文件是不受影响的,softfile已经不存在了,因为它链接到的file已经不存在了 image.png

其他对比

以下是官方给出的pnpm与npm和yarn的对比

标题pnpmyarnnpm工作空间支持(monorepo)✔️✔️✔️隔离的 node_modules✔️ - 默认✔️❌提升的 node_modules✔️✔️✔️ - 默认自动安装 peers✔️ - 通过 auto-install-peers=true❌✔️Plug'n'Play✔️✔️ - 默认❌零安装❌✔️❌修补依赖项❌✔️❌管理 Node.js 版本✔️❌❌有锁文件✔️ - pnpm-lock.yaml✔️ - yarn.lock✔️ - package-lock.json支持覆盖✔️✔️ - 通过 resolutions✔️内容可寻址存储✔️❌❌动态包执行✔️ - 通过 pnpm dlx✔️ - 通过 yarn dlx✔️ - 通过 npx 安装和使用 安装 使用独立脚本

curl -fsSL https://get.pnpm.io/install.sh | sh - 或者 wget -qO- https://get.pnpm.io/install.sh | sh -

使用npm安装

npm install -g pnpm

使用homebrew安装

brew install pnpm

使用

以下是列出常用的命令,具体可以参考官网管理依赖

安装依赖包

pnpm add

CommandMeaningpnpm add sax保存到 dependenciespnpm add -D sax保存到 devDependenciespnpm add -O sax保存到 optionalDependenciespnpm add -g saxInstall package globallypnpm add sax@next从 next 标签下安装pnpm add [email protected]安装指定版本 3.0.0 下载所有依赖

pnpm install or pnpm i

指定的范围更新软件包的最新版本

pnpm update or pnpm up

CommandMeaningpnpm up遵循 package.json 指定的范围更新所有的依赖项pnpm up --latest更新所有依赖项,此操作会忽略 package.json 指定的范围pnpm up foo@2将 foo 更新到 v2 上的最新版本pnpm up "@babel/*"更新 @babel 范围内的所有依赖项 删除依赖

pnpm remove or pnpm rm or pnpm uninstall or pnpm un

运行脚本 运行一个在 package的 manifest 文件中定义的脚本:pnpm run 运行在 package 的 scripts 对象中test 属性指定的任意的命令:pnpm test 从 create-* 或 @foo/create-* 启动套件创建项目:pnpm create,例如pnpm create react-app my-app 运行在 package 的 scripts 对象中start 属性指定的任意的命令:pnpm start orrun start

参考文章 剖析Npm、Yarn 与 Pnpm 依赖管理逻辑

什么是PNPM?

关于现代包管理器的深度思考——为什么现在我更推荐 pnpm 而不是 npm/yarn?

为什么推荐使用pnpm

都2022年了,pnpm快到碗里来!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3