关于pnpm10导致vscode-eslint插件失效
环境说明:
node:v20.19.1
pnpm:v10.*
eslint:v8.57.0
今天开发时发现在commit的时候husky报错了,但是IDE却没有对应的报错,于是去看了看控制台的Eslint的日志,大概内容是找不到@typescript-eslint/eslint-plugin这个文件。
前往根目录下的node_modules下查找这个库,确实是没有找到@typescript-eslint这个文件夹,于是顺着.eslintrc.js的依赖往下找,找到.pnpm中的某个包,发现其是有对应的@typescript-eslint/eslint-plugin包的,按照node的寻址方式会往外层的node_modules下进行寻找,理论上会找得到,为什么会寻找不到呢。
前几天在一个有段时间没开发的项目下也遇到了这个问题,当时以为是因为换了macos的问题,直接把缺失的包在外层显式安装就解决了。但是今天又遇到了这个问题,因为假期前还开发了,今天突然就跑不通了。于是决定好好研究一下:
在cursor的帮助下,终于分析出了原因。
原因是在前几天因为某些原因重装了nvm和node,当时顺手也就把pnpm升级到了最新的版本,该项目之前一直是pnpm9的,而在pnpm的changelog可以看到原来在pnpm10中,不会再将包含eslint和prettier的包提升到最外层的node_modules下(pnpm的特色是解决了从前npm的幽灵依赖问题,避免项目可以引入间接依赖的包,所以正常来说@typescript-eslint/eslint-plugin不会出现在最外层的node_modules下)而在pnpm9及其以前的版本是会将其提升的,所以为什么之前使用pnpm9的时候就不会有这个问题。
而之前之所以会提升就是因为.eslintrc.js的方式下的eslint插件会在最外层的node_modules下开始寻找,而为了兼容npm所以pnpm有了这个配置。
以下是对应的pnpm ChangeLog截图
详情可以查看这里:对应的pnpm的changeLog在10.0.0的更新日志中可以看到这一点
如何解决:
-
回退pnpm到9及其之前版本
-
更新eslint为扁平化配置,即通过eslint.config.js进行配置
-
可以配置pnpm-workspace.yaml下的publicHoistPattern属性,将包含eslint的包提升到最外层(但是这也会导致幽灵依赖的问题,算是被迫兼容,毕竟早期要是不这么干,那么pnpm就兼容不了eslint插件了,这就谈不上npm的上位替代品了)
publicHoistPattern: - "*eslint*"
同样问题的pnpm issues