前言
前段时间在做公司内部lint包的时候,在集成到目标项目过程中出现了vscode插件无法正确识别依赖包的问题,导致功能失效
依赖提升
前置知识点
众所可能大家都周知,pnpm对于根路径下的package.json中显示声明的依赖会安装在node_modules的一级目录,而对于间接依赖,则会放在node_modules/.pnpm目录下
可能引发的问题
那这样的机制对于开发会有什么样的问题呢?
不知道大家用过Taro没有,Taro是可以以string[]的形式引入插件的,查找机制是通过声明的插件名称在node_modules的目录中去匹配依赖,也就是说这个逻辑是写在Taro源码中的
设想这样一个场景:我们对Taro配置做了一层抽象,其中用到了一些插件包BCD,把这些插件包作为依赖项放在了Taro的配置包A里,这时候在目标工程中安装A包的时候,包BCD作为间接依赖被安装在node_modules/.pnpm目录下,导致Taro查找不到这些插件包,那这样就出现了功能问题
lint包的问题排查
在做lint包的时候,我把eslint、prettier、stylelint声明为lint包的依赖,这样做有两个收益:
- 我们可以在
lint包做统一的版本管理,在做渐进式升级的时候只需要升级lint包即可 - 接入方就不需要再安装一次这些
lint依赖
安装完出现了一个出乎认知外的问题,eslint和prettier依赖安装在了一级目录下,而stylelint则乖乖的躺在了.pnpm目录下
哦吼~这是个什么情况?而且这样的一个目录结构还导致了另外一个问题,因为stylelint依赖不是放在一级目录下,导致vscode的stylelint插件报错
对于这种超出认知外的问题是最难受的,因为连问题描述都写不出来,查都查不了。不过我们现在有AI,kimi启动!!!
-
将依赖关系和
node_modules的依赖截图给AI,让其分析为什么eslint等非直接依赖会安装在pnpm的一级依赖中 -
回答中没有有效信息,反问为什么
stylelint没有提升 -
回答分析可能是
public-hoist-pattern的原因,但我什么内容都没配置 -
然后将
lock文件和.modules.yaml文件发给AI(.modules.yaml是放在node_modules目录下,用于定义依赖的解析规则和安装路径),让其排查stylelint为什么没有提升 -
回答是
.modules.yaml文件中publicHoistPattern自动配置了eslint和prettier,缺失了stylelint,所以导致stylelint没有提升到一级依赖,这是pnpm内部提升算法自动添加的!
- 最后在.
npmrc把eslint、prettier、stylelint都配置到public-hoist-pattern,还有另外一种方案:在pnpm-workspace.yaml配置public-hoist-pattern
总结
pnpm会将一级依赖安装在node_modules一级目录下,间接依赖会安装在node_modules/.pnpm目录下,但不是绝对的pnpm内部存在依赖提升(hoisting)的算法机制。依赖提升是pnpm用来解决依赖版本冲突和重复安装问题的一种方法,它将共享依赖提升到一个公共的位置,使得所有依赖它们的包都能访问到同一个版本的依赖项。- 可以通过在.
npmrc或pnpm-workspace.yaml文件中显式配置public-hoist-pattern,用来强制提升所需依赖
最后,与君共勉