为什么我选择在项目中使用 pnpm?

为什么我选择在项目中使用 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。

为什么我选择在项目中使用 pnpm?

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

为什么我选择在项目中使用 pnpm?

可以看见 express 下面还有 node_modules,而内层 node_modules 中依赖的包里面还有 node_modules。

也就是说 npm2 的依赖是嵌套存在的。初一看这样是没有问题的,但是我们仔细思考,引入的包之间难免会有共同的依赖,如果同样的依赖复制很多次,会浪费磁盘空间。同时,嵌套还会导致文件路径过长,而在 windows 操作系统下,文件路径会被限制。

当时 npm 官方还没解决,yarn 就诞生了。

yarn & npm

yarn 通过扁平化,将所有依赖平铺,不再一层一层嵌套,解决依赖重复的同时,也解决了路径过长的问题。

我们把 node_module 删除,利用 nvm 切换 node 版本为 16.18.1,在命令行中输入 yarn,安装依赖:

为什么我选择在项目中使用 pnpm?

我们会发现明明 dependencies 下只有 express,但是 node_modules 下却有巨量的包,包内展开大部分没有第二层 node_modules。

npm 升级到 v3 版本后,也和 yarn 采用的类似平铺这种方案。

那这样是否就万事大吉了?

幽灵依赖问题

这样的解决方案也同时带了了另一个问题:明明没有出现在 dependencies 里面的依赖,在代码中却可以直接引用,而并没有显式依赖,当项目中其他的包不依赖这个包了,那我们的代码也就跑不起来了,因为依赖的这个包并不会被安装。这就是我们所说的幽灵依赖问题。

结构不确定性

而且当多个依赖包的依赖有不同版本时,只会提升一个版本到第一层 node_modules,而其他的版本也会以 npm2 的方式嵌套存在在内层的 node_modules 中。

为什么我选择在项目中使用 pnpm?
扁平化算法本身复杂度很高,耗时较长

pnpm 的出现

之后,pnpm 就诞生了。

为什么会出现 pnpm ?pnpm 的全称为 performance npm,翻译过来为高性能的 npm。原因是 pnpm 的作者一开始对 yarn 的发布有很高的期待,但是发布之后并没有满足作者,反而让作者有些失望。

至今 pnpm 发展迅速, 2022 年的下载量是 2021 年的 5 倍以上:

为什么我选择在项目中使用 pnpm?

那就让我们来看一下 pnpm 的各个特点。

二、pnpm 的特点

速度快

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

为什么我选择在项目中使用 pnpm?

节约磁盘空间

pnpm 通过硬链接、软链接来解决依赖嵌套和磁盘占用问题的。

这是一种操作系统提供的机制,首先介绍一下 inode。

inode 是索引节点,用来存储文件元信息,比如文件的创建者、文件的创建日期、文件大小等,打开文件时,系统首先找到文件的 inode 号码获取 inode 信息,再根据 inode 中的文件数据所在的块读取数据。其中多个文件可以指向源文件同一 inode,删除其中一个文件不影响另一个文件的访问,文件内容修改会同步到所有文件。

说文件硬链接,意思是和源文件都指向同一个 inode。

为什么我选择在项目中使用 pnpm?

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

为什么我选择在项目中使用 pnpm?

pnpm 就是通过硬链接、软链接来实现的,只在全局仓库中保存一份包的内容,当项目有需要的时候,通过硬链接到全局仓库,使用项目所依赖的包,而项目依赖包之间的依赖关系通过软链接建立。

我们将最开始的那个示例用 pnpm 安装一次:

为什么我选择在项目中使用 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

(0)
李, 若俞的头像李, 若俞

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!