pnpm:包管理的新星,平替 npm 和 yarn

pnpm,一个老牌的 node.js 包管理器,支持 npm 的所有功能,完全足以用来替代 npm。它采用全局存储,每个项目内部使用了硬链接,所以很省空间,安装速度快。

本文介绍下 pnpm 的基本概念,安装、卸载、使用,原理,可能遇到的问题及解决办法。

阅读本文需要一点前端基础,最好有过 Node 使用经历。

在 pnpm 出现之前...

和其他编程语言的包管理器不同,Node 会将安装的依赖放在每一个项目内。也就是说,如果你有两个项目,并且都用到了某个依赖,那么这个依赖会在两个项目内都下载一份。

这就导致有很多重复的依赖被下载,浪费了不少时间,占用了不少磁盘空间;当删除某个项目(哪怕是小项目)的时候,删除时间也会变得很长。

当然,换个角度想也可以算好处:

  • 对于设计 npm 的人来说,这是最省事的包依赖方法。就好比 Maven 安装依赖之后自动将 jar 包安装到项目的 lib 里面
  • 可以随意改代码。node_modules 里面的东西可以随便改,无需担心对其它项目的影响。

而 pnpm 将所有依赖存储在硬盘上的某一位置。当软件包被被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间,这允许我们跨项目地共享同一版本的依赖;安装时间也会快很多——因为对于已经有的依赖,不用再次下载。

简介

pnpm,全称 Performant npm,意思为“高性能的 npm”。pnpm 由 npm/yarn 衍生而来,解决了 npm/yarn 内部潜在的 bug,极大的优化了性能,扩展了使用场景,被誉为最先进的包管理工具。

官网(支持中文):https://pnpm.io

开源在 GitHub:https://github.com/pnpm/pnpm,目前已获 30k Star

特点:

  • 快速:比 npm 快了近 2 倍(可以参考官方的 测试结果
  • 高效:node_modules 中的所有文件均克隆或硬链接自单一存储位置
  • 支持 monorepos(大型前端项目的代码管理方式)
  • 权限严格:默认创建了一个非平铺的 node_modules,因此代码无法访问任意包
  • 流行:数十家大公司都在用(微软,字节跳动,Shopee,Vue...)
  • 更多和 npm/yarn 的功能比较,可以参考官网的说明
  • ......

安装

安装之前,最好先确定好安装什么版本的 pnpm,因为它并不兼容 Node.js 的所有版本。官方列出的表格:

Node.js pnpm 7 pnpm 8 pnpm 9
Node.js 12
Node.js 14 ✔️
Node.js 16 ✔️ ✔️
Node.js 18 ✔️ ✔️ ✔️
Node.js 20 ✔️ ✔️ ✔️

可以通过 node -v​ 来查看当前 node​ 版本,然后就可以安装了,支持多种安装方式(请参考 官方安装文档),这里列两个:

  • 通过 Node 安装:npm i -g pnpm
  • 通过 HomeBrew:brew install pnpm

注意:

  • 不能通过 cnpm,yarn 安装
  • 如果要指定版本,可以先通过 npm view pnpm versions​ 查看所有版本,然后安装时指定:npm i -g pnpm@7.0.1

安装完后,重新打开 cmd,查看当前 pnpm 版本:

pnpm -v

配置

安装好后,我们可以做些配置,使其更好用。

配置镜像源

当我们使用 pnpm,也是要从镜像源去下载包的,我们可以看看当前的镜像地址:

pnpm get registry
or
pnpm config get registry

我们可以全局设置新的镜像地址(例如淘宝源):

pnpm set registry https://registry.npmmirror.com

如果想单独为某个项目设置:

pnpm config set registry https://registry.npmmirror.com --save

其他源:

配置完后,可以再次查看下当前的源,确保修改生效。

题外话,可以看到 pnpm 和 npm 的配置相关命令格式很像,这是因为 pnpm uses npm's configuration formats.

配置安装包路径

pnpm 会将下载后的包放到默认路径下。除了依赖,还有缓存等数据也会放到默认路径。

我们可以修改这个默认路径,例如放到 D 盘:

# pnpm 全局仓库路径(类似 .git 仓库)
pnpm config set store-dir "D:\pnpm\store" 

# pnpm 全局安装路径
pnpm config set global-dir "D:\pnpm\global" 

# pnpm 全局安装包的 bin 路径
pnpm config set global-bin-dir "D:\pnpm\global-bin" 

# pnpm 创建 pnpm-state.json 文件的目录,该文件仅用于 pnpm 内部的更新检查器使用
pnpm config set state-dir "D:\pnpm\state" 

# pnpm 全局缓存路径
pnpm config set cache-dir "D:\pnpm\cache"

配置完后,可以检查下:

# 查看全局安装包位置
pnpm config get global-bin-dir

# 或者
pnpm store path

# 也可以查看所有配置
pnpm c get

配置环境变量

在某些情况下,可能需要手动配置环境变量以确保 pnpm 能够全局访问。例如,在我修改了全局安装包路径后。

我们可以先运行 pnpm setup,它会添加环境变量。注意:

  1. 看看是否存在名为 %PNPM_HOME%​ 的环境变量,没有则创建,值为刚刚指定的路径,例如 D:\pnpm\global-bin
  2. 在系统变量 PATH​ 里添加 %PNPM_HOME%

配置别名

pnpm 有四个字母,我感觉还是蛮长的,我们可以给其设置别名,提高效率。在官网的安装文档里也有说:

想在 POSIX 系统上添加永久别名,只需在 .bashrc​, .zshrc​, or config.fish​ 文件里添加:

alias pn=pnpm

想在 Windows 里添加,先在具有管理员权限的 Powershell 窗口中执行:

notepad $profile.AllUsersAllHosts

然后在 profile.ps1​ 文件里键入如下内容:

set-alias -name pn -value pnpm

保存文件并关闭。需要关闭所有打开的 Powershell 窗口,能使别名生效。


还有网友专门写了个项目:my-pnpm,内置了各种缩写,非常方便

使用

pnpm 的使用,和 npm 差不多:

含义 npm 命令 pnpm 命令
安装所有依赖 npm install pnpm install
安装指定包 npm install package pnpm add package
移除指定包 npm uninstall package pnpm remove package
运行脚本 npm run 脚本 pnpm 脚本

可以看到运行脚本时,pnpm 不需要添加参数 run,更简洁。

例如,全局安装 yrm(一个管理镜像源的包):

pnpm i -g yrm

在项目内使用也是一样的。我们可以随机打开一个项目,将 node_modules 删掉,然后执行 pnpm i​,输出的内容大致长这样:

可以看到有 reused​,即利用了已经下载过的 192 个依赖;downloaded​ 为 0,说明没有下载新的依赖。

此时新的 node_modules 大概长这样:

可以看到,依赖项减少了很多,直接依赖都会在 node_modules 里列出来,可以很方便地看源码;而其他的则都放到了 .pnpm​ 文件夹里。

此外,还能看到一个 pnpm-lock.yaml 文件,这个也是用来锁定版本的

更新和卸载

pnpm 是在不断更新中的,想用新版本,一条命令即可:

pnpmp self-update

如果想要卸载,请参考官方文档:https://pnpm.io/zh/uninstall

最后

pnpm 日常使用起来还是不错的,速度快,节省了很多时间,推荐使用。

参考

Pnpm:包管理的新星,如何颠覆 Npm 和 Yarn

PNPM 设置全局包的安装路径,给 PNPM 设置不一样的家

pnpm 基本详细使用教程(安装、卸载、使用、可能遇到的问题及解决办法)

PNPM包管理工具_哔哩哔哩

原文:pnpm:包管理的新星,平替 npm 和 yarn

posted @ 2024-11-18 10:10  peterjxl  阅读(650)  评论(6编辑  收藏  举报