pnpm
-
支持monorepo
- 替代lerna
-
速度快
-
节省磁盘空间
- 1、如果你对同一依赖包需要使用不同的版本,则仅有 版本之间不同的文件会被存储起来。例如,如果某个依赖包包含 100 个文件,其发布了一个新 版本,并且新版本中只有一个文件有修改,则
pnpm update只需要添加一个 新文件到存储中,而不会因为一个文件的修改而保存依赖包的 所有文件
一个包的不同版本,pnpm 可以复用之前版本的代码。只会下载新版本的新文件,会复用之前版本的文件
- 2、所有文件都保存在硬盘上的统一的位置。当安装软件包时, 其包含的所有文件都会硬链接自此位置,而不会占用 额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的 依赖包。
- 1、如果你对同一依赖包需要使用不同的版本,则仅有 版本之间不同的文件会被存储起来。例如,如果某个依赖包包含 100 个文件,其发布了一个新 版本,并且新版本中只有一个文件有修改,则
-
可以替代npm、yarn
硬连接就是同一个文件的不同引用,而软链接是新建一个文件,文件内容指向另一个路径
pnpm是如何解决幽灵依赖问题
- pnpm采用了软链接的方式去引用依赖
- 通过软链接可以把
.pnpm的包软链接到当前项目node_modules中,而不需要将包的源代码拷贝到当前项目,这种方式可以避免重复包拷贝和占用磁盘空间- 节省磁盘空间: 因为不需要在每个项目中复制依赖,所以节省了大量的磁盘空间。
pnpm为何速度快?
-
下载安装依赖的时候,pnpm会先检查
store目录,会从store目录硬链接到项目中,而不会重新安装依赖 -
一个包的不同版本,pnpm 可以复用之前版本的代码。只会下载新版本的新文件,会复用之前版本的文件
pnpm 为何节省空间?
- 1、它解决了 npm/yarn 平铺 node_modules 带来的依赖项重复的问题 (doppelgangers)
- 2、所有文件都保存在硬盘上的统一的位置。当安装软件包时, 其包含的所有文件都会硬链接自此位置,而不会占用 额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的 依赖包。
- 3、通过软链接可以把
.pnpm的包软链接到当前项目node_modules中,而不需要在每个项目中复制依赖
常用命令
- pnpm add: 安装依赖包
- pnpm dlx 【类似npx】
- pnpm run :运行scrips脚本,可简写
- 注意简写【仅适用于那些不与已有的 pnpm 命令相同名字的脚本】
- 比如如果scripts命令中存在deploy,简写执行pnpm deploy会有问题,pnpm会以为执行内置的命令,正确是 pnpm run deploy
- pnpm install
- pnpm -F : 选择指定的包
- pnpm publish : 发布
- pnpm publish -F 可以指定某个包发布
- pnpm publish -r 可以一键发布所有包
- pnpm -r : 每个项目中运行命令 【recursive递归】
- pnpm i -w :只在根目录的node_modules安装 【-w 指根目录】
- pnpm exec : 执行当前项目的依赖
- pnpm update: 根据指定的范围更新软件包的最新版本
- pnpm -C
<path>: 在<path>中启动 pnpm ,而不是当前的工作目录。 - pnpm -w : 在工作区根目录中启动pnpm
- pnpm deploy: 部署命令
- 将指定项目的代码与依赖以可移植的形式打包到目标目录
- 如
pnpm deploy --filter=@project/app dist- 将
@project/app的 项目文件(包括package.json、构建产物、配置等)完整复制到dist目录。默认包含所有文件,但可通过package.json的files字段控制包含内容
- 将
查看pnpm配置
- pnpm config get proxy : 查看代理
- pnpm config delete proxy:需要取消代理
- pnpm store path: 获取pnpm 的 store 目录所在的位置
pnpm配置代理镜像
- pnpm config set registry https://registry.npmmirror.com/
如配置electron镜像
pnpm config set electron_mirror https://mirrors.huaweicloud.com/electron/
pnpm config set electron_builder_binaries_mirror https://mirrors.huaweicloud.com/electron-builder-binaries/
pnpm的工作空间(Workspace)
pnpm 内置了对单一存储库(也称为多包存储库、多项目存储库或单体存储库)的支持, 你可以创建一个 workspace 以将多个项目合并到一个仓库中
引用 workspace 包
- 在 workspace 中有一个名为
foo的包, 通常你会像这样引用:"foo": "workspace:*" - 相对路径引入:bar
中可能有foo的依赖:"foo": "workspace:../foo"
当执行发布命令之后,pnpm publish, 会动态替换workspace参数
publishConfig问题
- 表示当publish发布命令的之后,要覆盖的字段
{
"name": "foo",
"version": "1.0.0",
"main": "src/index.ts",
"publishConfig": {
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}
}
将发布为:
{
"name": "foo",
"version": "1.0.0",
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}
.npmrc常用配置
- auto-install-peers
- 当值为
true时,将自动安装任何缺少的非可选同级依赖关系。
- 当值为
pnpm在软链接和硬链接作用是什么?
总结:
- pnpm在 硬链接的作用可以在不同项目之间共享pnpm的store目录
- pnpm在 软链接的作用 项目的node_modules这个文件夹中创建符号链接,包之间通过软链接的方式来相互引用依赖包,来复用相同版本的包依赖
- 如果项目A依赖于项目B中的某个包,pnpm会创建一个软链接,将该包链接到项目A的
node_modules中,而不是复制整个包。这可以节省磁盘空间
- 如果项目A依赖于项目B中的某个包,pnpm会创建一个软链接,将该包链接到项目A的
项目的所有的依赖都是从全局 store 硬链接到了 node_modules/.pnpm 下,然后之间通过软链接来相互依赖
硬链接:
.pnpm 中存放着所有的包。最终硬链接指向指向全局pnpm 仓库里的store目录下。
也就是说,我们所有的包,最终都以硬链接的形式,最终都在全局 pnpm/store 中,可以使得不同的项目从全局 store 寻找到同一个依赖,大大节省了磁盘空间。
- 硬链接的作用可以在不同项目之间共享store文件
与软链接相比,硬链接的好处是它创建的链接可以被看作是源文件的副本,对应的文件节点数会增加,但它不会占用额外的磁盘空间,因为硬链接和源文件共享磁盘上的同一个数据块,只有在硬链接被删除时,才会释放对应的数据块
软链接:
pnpm 的软链接就是将 node_modules 里的文件软链接到对应的 .pnpm/[package_name]@version/node_modules/[package_name] 中。【pnpm软链接就是将node_mudules的文件软链接到对应的pnpm某个包的某个版本】
- 软链接的设计保证不会出现幽灵依赖的问题
- 通过软链接可以把
.pnpm的包软链接到当前项目node_modules中,而不需要将包的源代码拷贝到当前项目,这种方式可以避免重复包拷贝和占用磁盘空间- 通过软链接来相互依赖
- 软链接的作用是将一个包的源代码链接到多个项目中,避免在每个项目中都拷贝一份源代码
node_modules/.pnpm 可以理解为虚拟 store
npm2 是通过嵌套的方式管理 node_modules 的,会有同样的依赖复制多次的问题。
npm3+ 和 yarn 是通过铺平的扁平化的方式来管理 node_modules,解决了嵌套方式的部分问题,但是引入了幽灵依赖的问题,并且同名的包只会提升一个版本的,其余的版本依然会复制多次。
为什么会出现复制多次?
- 多个包之间难免会有公共的依赖,这样嵌套的话,同样的依赖会复制很多次,会占据比较大的磁盘空间
pnpm 则是用了另一种方式,不再是复制了,而是都从全局 store 硬链接
到 node_modules/.pnpm,然后之间通过软链接来组织依赖关系。
补充知识点:
- 软链接:
- 软链接,也称为符号链接,它创建一个特殊类型的文件,其中包含指向另一个文件或目录的路径
- 如果源文件被删除了,软链接会保留下来,但是会失效
- 移除源文件不会移除快捷方式
- 软链接会占用磁盘空间
- 硬链接:
- 硬链接是文件系统中的一种特殊链接,它允许一个文件存在于多个位置,但在磁盘上只占用一个存储空间
- 移除源文件不会影响硬链接
- 移除硬链接不会影响源文件
- 如果源文件被删除,它的内容依然通过硬链接存在
- 硬链接文件的任何更改都会影响到源文件
- 硬链接并不占用额外的磁盘空间
为什么硬链接并不占用额外的磁盘空间?而软链接会占用磁盘空间
-
硬链接:在操作系统内部创建了一个指向另一个文件的新文件名,硬链接并不包含文件路径信息,而是直接指向另一个文件的 inode【即文件索引节点,包含了文件的元数据和实际数据块的位置信息】
- 如果源文件被删除,硬链接会一直存在,除非你明确地将它删除
-
软链接会包含文件的路径,当你使用软链接时,操作系统会读取软链接文件中包含的路径,然后转到真正的文件操作
- 如果源文件被删除,软链接仍然存在,但是它将失效,因为它所指向的文件已经不存在
- 软链接的大小取决于软链接文件中包含的路径信息的长度
如果源文件被删除,为什么硬链接仍然有效?
- 如果源文件被删除,硬链接仍然有效,因为它只是对另一个文件的新文件名的引用。即使源文件被删除,硬链接仍然可以指向另一个文件的 inode,并且仍然可以使用硬链接访问源文件的数据
如果源文件被删除了,为什么软链接会失效?
- 如果源文件被删除,软链接仍然存在,但是它将失效,因为它所指向的文件已经不存在。这意味着,如果你尝试使用软链接访问源文件,操作系统将会返回一个错误消息,表示文件不存在。
pnpm 弊端
调试问题
所有项目引用的包都在全局一个地方,如果想对某个包进行调试,其他项目正好引用了,本地运行也会收到影响。