为什么我选择在项目中使用 pnpm?
一、什么是 pnpm?
总览
pnpm
的 官网(https://pnpm.io/) 中是这样介绍 pnpm 的:
Fast, disk space efficient package manager
意思是快速,占用磁盘空间少
的包管理工具
。
可见,pnpm 是和 npm、yarn 一样的包管理工具,但是其具有快速、占用磁盘空间少等特点。
对比
在了解 pnpm 的特点之前,我们先来看一下 npm 和 yarn 都分别存在哪些问题。
npm2
我们通过 nvm(管理 node 版本的工具)将 node 降为 v4.9.1,这时 npm 的版本就为 v2.15.11。

之后我们通过 npm init -y,默认配置创建 package.json,再 npm i express 安装 express。

可以看见 express 下面还有 node_modules,而内层 node_modules 中依赖的包里面还有 node_modules。
也就是说 npm2 的依赖是嵌套存在
的。初一看这样是没有问题的,但是我们仔细思考,引入的包之间难免会有共同的依赖,如果同样的依赖复制很多次,会浪费磁盘空间
。同时,嵌套还会导致文件路径过长
,而在 windows 操作系统下,文件路径会被限制。
当时 npm 官方还没解决,yarn 就诞生了。
yarn & npm
yarn 通过扁平化
,将所有依赖平铺
,不再一层一层嵌套,解决依赖重复的同时,也解决了路径过长的问题。
我们把 node_module 删除,利用 nvm 切换 node 版本为 16.18.1,在命令行中输入 yarn,安装依赖:

我们会发现明明 dependencies 下只有 express,但是 node_modules 下却有巨量的包,包内展开大部分没有第二层 node_modules。
npm 升级到 v3 版本后,也和 yarn 采用的类似平铺这种方案。
那这样是否就万事大吉了?
幽灵依赖问题
这样的解决方案也同时带了了另一个问题:明明没有出现在 dependencies 里面的依赖,在代码中却可以直接引用,而并没有显式依赖,当项目中其他的包不依赖这个包了,那我们的代码也就跑不起来了,因为依赖的这个包并不会被安装。这就是我们所说的幽灵依赖问题。
结构不确定性
而且当多个依赖包的依赖有不同版本时,只会提升一个版本到第一层 node_modules,而其他的版本也会以 npm2 的方式嵌套存在在内层的 node_modules 中。

扁平化算法本身复杂度很高,耗时较长
pnpm 的出现
之后,pnpm 就诞生了。
为什么会出现 pnpm ?pnpm
的全称为 performance npm,翻译过来为高性能的 npm。原因是 pnpm 的作者一开始对 yarn 的发布有很高的期待,但是发布之后并没有满足作者,反而让作者有些失望。
至今 pnpm 发展迅速, 2022 年的下载量是 2021 年的 5 倍以上:

那就让我们来看一下 pnpm 的各个特点。
二、pnpm 的特点
速度快
从 pnpm 官网提供的数据来看,作为黄色的 pnpm 安装速度在绝大部分场景下都是优于 npm、yarn 的,速度有的甚至还快出 2~3 倍。

节约磁盘空间
pnpm
通过硬链接、软链接来解决依赖嵌套和磁盘占用问题的。
这是一种操作系统提供的机制,首先介绍一下 inode。
inode
是索引节点,用来存储文件元信息,比如文件的创建者、文件的创建日期、文件大小等,打开文件时,系统首先找到文件的 inode 号码获取 inode 信息,再根据 inode 中的文件数据所在的块读取数据。其中多个文件可以指向源文件同一 inode,删除其中一个文件不影响另一个文件的访问,文件内容修改会同步到所有文件。
说文件硬链接,意思是和源文件都指向同一个 inode。

软链接也叫符号连接,软连接是一个链接文件,指向源文件的地址。

pnpm
就是通过硬链接、软链接来实现的,只在全局仓库中保存一份包的内容,当项目有需要的时候,通过硬链接到全局仓库,使用项目所依赖的包,而项目依赖包之间的依赖关系通过软链接建立。
我们将最开始的那个示例用 pnpm 安装一次:

pnpm 提示我们在终端提示我们虚拟仓库通过硬链接到全局仓库,这里的虚拟仓库就是指我们项目的包仓库。

在第一层 node_modules 下,只有 express 这一个依赖包,而 express 下没有 node_modules,因为这里的 express 只是一个软链接。而 express 的真实位置在 .pnpm 下,.pnpm 是以平铺的形式存储着所有的包的。
支持 monorepo
随着前端工程的复杂度提升,越来越多的项目选择采用 monorepo
,什么是 monorepo?就是用一个 git 仓库来管理多个项目,所有的子项都放在 package 目录下,一个子项目就代表一个 package。而我们以往的开发模式是一个 git 仓库只对应一个项目。
pnpm 默认就支持 monorepo
。
安全性高
在节约磁盘空间特点部分的最后,提到了 pnpm 同样也是扁平化展开的。但是 pnpm 的扁平化展开和 npm、yarn 不同,其保留了包之间的相互隔离,因为其平铺的依赖中的所有依赖也是通过软链的形式链接到 .pnpm 中的对应依赖的。
文章出自:https://juejin.cn/post/7220396538689962042
作者:cheerioInf
原文始发于微信公众号(前端24):为什么我选择在项目中使用 pnpm?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/216094.html