使用可能会遇到的问题
pnpm官网罗列了一些在使用过程可能会遇到的问题,具体有以下几个方面:
peer dependencies 如何解决
npm workplace
首先我们需要先了解一下npm workplace
或者 yarn workplace
,工作空间的概念。
Workspaces
是一个通用术语,指的是 npm cli 中的一组功能,这些功能支持从单个顶级根包中管理本地文件系统中的多个包。 这组功能弥补了从本地文件系统处理链接包的更加简化的工作流程。自动链接过程作为 npm install 的一部分,避免手动使用 npm link 来添加对应该符号链接到当前 node_modules 文件夹中的包的引用。
简单的说,npm workplace
主要用来解决以下几个问题:
- 在同一个git仓库中管理多个npm包
- 同时npm包之间可以存在互相依赖
- 多个子项目会依赖一些公共的npm包
- 减少之前因为
npm link
管理的混乱
peerDependencies
通过上面npm workplace
概念了解,当工作区里有多个子项目需要依赖一些公共的npm包,但是这些公共npm包版本可能大家所需要的都不一样,这个时候就需要peerDependencies
去描述依赖和版本。它是这么定义的:
在开发插件时,你的插件需要某些依赖的支持,但是你又没必要去安装,因为插件的宿主回去安装这些依赖。此时就可以用
peerDependencies
去声明一下需要依赖的插件和版本。如果出问题的话,npm 会有警告来提示使用者去解决版本中的冲突。
因此,peerDependencies
的目的很清晰,就为了解决workplace下不同子项目中公共依赖包版本问题。
所以回到pnpm
中,由于pnpm
是认定项目中只有一组npm
依赖树,那么针对workplace中的 peerDependencies
,它是如何解决的呢?
pnpm
的解决方案是:为不同的peerDependencies
依赖项创建不同的解析。
如何理解这句话呢?参考官网的解释:
当有两个子项目,他们的依赖分别如下:
- foo-parent-1 - bar@1.0.0 - baz@1.0.0 - foo@1.0.0 - foo-parent-2 - bar@1.0.0 - baz@1.1.0 - foo@1.0.0
foo-parent-2
或foo-parent-1
公共依赖了baz
,但是要求版本不一样,如果这个时候项目中没有声明peerDependencies
,.pnpm store
中保存的依赖树如下:
node_modules └── .pnpm ├── foo@1.0.0 ├── bar@1.0.0 ├── baz@1.0.0 ├── baz@1.1.0
如果有声明peerDependencies
,pnpm
会根据不同的peerDependencies
创建对应的链接,.pnpm store
中保存的依赖树如下:
node_modules └── .pnpm ├── foo@1.0.0_bar@1.0.0+baz@1.0.0 #不同声明peerDependencies所创建的链接目录 │ └── node_modules │ ├── foo │ ├── bar -> ../../bar@1.0.0/node_modules/bar │ ├── baz -> ../../baz@1.0.0/node_modules/baz ├── foo@1.0.0_bar@1.0.0+baz@1.1.0 #不同声明peerDependencies所创建的链接目录 │ └── node_modules │ ├── foo │ ├── bar -> ../../bar@1.0.0/node_modules/bar │ ├── baz -> ../../baz@1.1.0/node_modules/baz ├── baz@1.0.0 ├── baz@1.1.0
通过创建不同的peerDependencies
的链接,去解决不同子项目中的依赖包版本问题。
hosited配置
pnpm从2022年初支持hoisted
配置,可以在 .npmrc
文件中使用 node-linker=hoisted
设置。
新增该设定,是为了基本上使 pnpm 可以兼容所有与 npm CLI 兼容的 Node.js 技术栈。
删除npm包
这个是个人的疑问,既然将所有的依赖包统一归置到.pnpm store
管理,那么针对一些过期或者无用的npm包什么时候进行删除呢?
pnpm的给出的方案如下:
- 设置npm包的有效期,可以在
.npmrc
配置中设置modules-cache-max-age配置项,单位为:分钟,默认值:10080,7天 pnpm prune
, 从存储中删除未引用的包
其他问题
官网同时也提出未解决的问题:
- 针对
package-lock.json
等锁文件更新,npm允许每次安装同样版本的npm包可能会更新lock文件,从而更新node_modules
文件内容,但是pnpm由于创建隔离布局,无法实时按照package-lock.json
的更新而更新,因此pnpm推荐将使用pnpm import
命令将package-lock.json
等文件转为pnpm-lock.yaml
这个问题就是pnpm没法按照项目现有的package-lock.json
去做自动更新,只能通过pnpm import
去做转换。
总结
pnpm
确实给前端开发带来一些提醒,让我们关注到平时可能已经习惯的问题,比如npm
包管理混乱导致的问题,虽然存在但是我们已经忽略或者已经习惯了。
总结一下学习pnpm
后,在实际项目中引用会给我们带来什么:
- 提高我们本地开发效率,毕竟多个前端项目同时在电脑,每次安装或更新都需要等待一段时间
- 提高项目的编译速度,利用
.pnpm store
在编译机上,不用每次都重新安装 - 提高项目npm依赖的安全性,清晰明白项目中npm依赖结构,不用担心非法npm包在项目中被开发使用
这里联想扩展几个问题点:
- 什么时候node.js才能支持es6的import和export
- node.js或者浏览器,什么时候才能直接加载远程js包,而不是需要安装到本地才能使用