npm/yarn/pnpm/cnpm

248 阅读6分钟

包管理器

包管理器是前端开发中用于管理和安装项目所需外部库、框架和依赖项的重要工具。它们通过自动化依赖项的获取、安装、更新和版本控制,大大简化了前端开发的工作流程,使开发者能够更专注于应用的构建和功能的实现。 主流前端包管理器:npm(Node Package Manager)、Yarn、pnpm等。

npm/yarn/pnpm/cnpm

npm:是 Node.js 的默认包管理器,随 Node.js 一起安装。它拥有一个庞大的在线数据库(npm registry),包含了数百万个包(libraries)。它可以根据项目的依赖关系,自动下载并安装所有需要的包。支持安装、更新、配置和卸载依赖项,提供命令行客户端,支持脚本运行、发布包和版本控制。 npm 5 之后引入了 package-lock.json 文件,用于锁定依赖的版本,确保安装一致性。

常用命令:

  • npm config list:查看当前npm配置;
  • npm config get [config-key]:查看某一项配置项;
  • npm config set registry [url]:设置镜像源;
  • npm cache clean --force:清除npm缓存;
  • npm install npm@latest -g:更新最新版本;
  • npm install --legacy-peer-deps:v7中引入的,在npm7或更高版本中,npm默认会安装peerDependencies,这可能会导致版本冲突,从而中断安装过程。通过添加--legacy-peer-deps标志,npm会忽略peer依赖项的版本检查,并继续安装指定的依赖项,允许项目中的各个依赖模块(modules)使用不同版本的相同模块共存,项目继续运行,从而绕过自动安装peerDependencies可能带来的问题。因此在安装依赖时有版本不匹配导致安装失败报错时可以尝试加上--legacy-peer-deps
    • nrm:一个npm源管理器,允许你快速地在npm源间切换。使用步骤:
    • 全局安装nrm:npm install -g nrm
    • 执行命令nrm ls查看可选源;
    • 执行nrm use taobao切换镜像源;
    • 增加定制源nrm add registry [url]

yarn

Yarn 是由 Facebook、Google、Exponent 和 Tilde 联合创建的替代 npm 的包管理器。与 npm 类似,但提供了更快的安装速度、更稳定的包依赖管理以及更安全的安装流程。通过 yarn.lock 文件确保依赖的一致性。并行安装方式提高了安装速度,支持离线模式,能够重新安装已下载的包而无需互联网连接。

pnpm

pnpm是一个高效的npm包管理工具,旨在解决包依赖管理时的一些常见问题。pnpm使用一种称为“符号链接”的方法来管理包依赖,称为硬链接(hard links),这可以节省磁盘空间并提高安装速度,并确保同一个包的不同版本之间共享尽可能多的代码。更好的支持workspace 和 monorepo。

优点:

  • 安装速度快;

  • 节省磁盘空间,pnpm内部使用的是基于内容寻址存储的方式来存储依赖,是一种根据内容而不是位置进行检索信息的存储方式。这个方式优点在于不会重复安装同一个包,即便一个包的不同版本,pnpm也会极大程度的复用之前版本的代码。

  • 支持monorepo;

  • 安全性高,如果使用 npm/yarn 进行包管理,由于 node_module 的扁平结构,如果 A 依赖 B, B 依赖 C,那么 A 当中是可以直接使用 C 的,但问题是 A 当中并没有声明 C 这个依赖(幽灵依赖)。因此会出现这种非法访问的情况。但 pnpm 自创了一套依赖管理方式,很好地解决了这个问题,保证了安全性。

    幽灵依赖:明明没有在 package.json 的 dependencies 里声明某个依赖,但在代码里却可以 import 进来。这是因为项目依赖被铺平了,那么依赖的依赖自然也是可以被引入到项目中。幽灵依赖带来的弊端很明显:我们显式依赖了A,A又依赖了B,这时候我们在项目中直接使用B是不会报错的,但如果某一天A不再依赖于B,那么我们项目中使用B的地方就会报错。

    硬链接:(hard link)是计算机文件系统中的多个文件平等地共享同一个文件存储单元。比如两个不同路径下的两个二文件都硬链接了同一个文件存储单元,两者的信息内容其实是一致的,也就是说他们只是存储了引用,达成了一个映射关系,如果其中一个文件修改了内容,那么另外一个文件内容也会跟着变化。类似与javascript中对象的引用。硬链接的机制可以让多个不同的位置寻址到相同的空间。

    软链接:(符号链接、Symbolic link)是一类特殊的文件,其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用。它就相当于 windows 系统中的快捷方式。一个符号链接文件仅包含有一个文本字符串,其被操作系统解释为一条指向另一个文件或者目录的路径。它是一个独立文件,其存在并不依赖于目标文件。如果删除一个符号链接,它指向的目标文件不受影响。如果目标文件被移动、重命名或者删除,任何指向它的符号链接仍然存在,但是它们将会指向一个不复存在的文件。

    pnpm 使用软链接来创建依赖项的嵌套结构,将项目的直接依赖符号链接到node_modules的根目录,直接依赖的实际位置在.pnpm/<name>@<version>/node_modules/<name>,依赖包中的每个文件再硬链接到.pnpm store。

cnpm

淘宝镜像cnpm是为中国大陆用户定制的npm(Node Package Manager)镜像,由阿里巴巴的淘宝团队开发和维护。cnpm与npm的主要区别在于,cnpm是一个中国版的npm,主要用于解决网络下载速度慢的问题。

对比总结

npm或者是yarn,安装依赖时一般是下载该依赖的tar包到本地离线镜像,然后解压到本地缓存,最后再将其拷贝到项目的node_modules中。如果有100个项目,并且这100个项目都有一个相同的依赖包,那么这100个项目的node_modules中都保存有这个相同依赖的副本,也就是说硬盘上需要保存100份相同依赖包的副本。而pnpm通过 hard link (硬链接)的方式来实现了一样的依赖,只保存一份。pnpm安装依赖时,依赖包会被存放在统一的位置(称为store,可以通过命令pnpm store path获取store的位置),然后使用该依赖的项目会硬链接对应的依赖位置,也就是说所有用这个的依赖的项目都是通过硬链接的方式共享了同一份store上的依赖。而且后续安装依赖时,如果该依赖之前已经安装过了,在store中已经有了该依赖,这时候就会直接使用hard link,大大减少安装时间。