从pnpm到npm的核心管理机制(二)

简介: 使用可能会遇到的问题

使用可能会遇到的问题


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-2foo-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

如果有声明peerDependenciespnpm会根据不同的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包,而不是需要安装到本地才能使用

参考资料


目录
相关文章
|
6月前
|
存储 缓存 资源调度
包管理npm、yarn、pnpm区别
包管理npm、yarn、pnpm区别
76 0
|
2月前
|
存储 缓存 资源调度
三巨头对决:深入了解pnpm、yarn与npm
三巨头对决:深入了解pnpm、yarn与npm
162 0
|
4月前
|
资源调度
pnpm : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本。
pnpm : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本。
|
4月前
|
缓存 资源调度 前端开发
npm、yarn、pnpm 如何删除缓存文件?
在前端工程化的环境下,频繁的安装、更新、移除依赖,总会产生一些不活跃的 npm 依赖包,一直隐藏在某个角落里。
79 5
|
4月前
|
存储 资源调度 JavaScript
PNPM(高性能的npm)介绍
PNPM(高性能的npm)介绍
PNPM(高性能的npm)介绍
|
5月前
|
资源调度
npm yarn 和 pnpm 之间命令的区别
npm yarn 和 pnpm 之间命令的区别
|
5月前
|
存储 资源调度 安全
你知道npm、yran、pnpm的区别吗?
你知道npm、yran、pnpm的区别吗?
43 0
|
16天前
|
网络安全 计算机视觉
【node】 npm install 报错:code 128
【node】 npm install 报错:code 128
34 1
|
1月前
|
JavaScript 内存技术
node与npm版本对应关系以及使用nvm管理node版本
node与npm版本对应关系以及使用nvm管理node版本
192 0
|
4月前
|
Ubuntu
node、npm 命令升级
node、npm 命令升级

推荐镜像

更多