爱站网关键词查询网站,公司排名seo,sem运营,h5响应式音乐网站模板最近我在使用 pnpm 作为包管理器开发一个 monorepo 项目#xff0c;从个人体验来说#xff0c;在 monorepo 项目中#xff0c;pnpm 确实要比 yarn classic 用得舒心#xff0c;最让我欣喜的是 pnpm 对 workspace 协议的支持度很好#xff1b;另外感受比较明显的一点就是从个人体验来说在 monorepo 项目中pnpm 确实要比 yarn classic 用得舒心最让我欣喜的是 pnpm 对 workspace 协议的支持度很好另外感受比较明显的一点就是开发过程中感知到的由于依赖层级导致的 bug 也变少了。
但是任何事情都不可能是完美的。果不其然一个关键的 bug 就在等着我。我在这个 pnpm monorepo 项目中尝试为一个子包生成 d.ts 类型声明文件时出现了一个 TS2742 错误。
error TS2742: The inferred type of default cannot be named without a reference to .pnpm/vueruntime-core3.3.4/node_modules/vue/runtime-core. This is likely not portable. A type annotation is necessary.从错误信息最后一句话看是需要加一个类型注解但是从我的使用场景来看相关类型应该是能够自动推导出来的不需要画蛇添足。感觉很奇怪
第一反应是检查下 .pnpm 目录下的对应的文件是不是都正常。经检查一切文件结构和软链接都正常。
然后就想着是不是代码引入 vue 相关的依赖时有问题。看了报错处都是很正常的一些引用比如
import { defineComponent } from vue但是从报错信息来看似乎是找不到 vue 内部的子包的相关类型难道是通过 vue 找内部包的时候出问题了
另外很奇怪的一点是VSCode 表现正常鼠标悬停类型提示正常面板也没有报出任何关于类型的错误。
无奈只能拿着错误信息去 google 搜索确实找到了 github 上一些关联度很高的 issueissue 来源包括 typescript, pnpm 等仓库。
microsoft/TypeScript#42873
microsoft/TypeScript#47663
这些 issue 在21年22年就提出了但是目前也还没有 Close。我试了 issue 讨论中提到的一些方法包括修改preserveSymlinks在项目根目录安装对应依赖设置 tsconfig.json 中的paths配置辅助 TypeScript 找到对应依赖的位置等但是最后都没有奏效可能是我的解决姿势不正确最终困扰了几天在 google, stackoverflow, github 上一无所获也尝试过 debug 去分析代码执行过程也没看明白。
解决方法1node-linkerhoisted
于是我在想是不是 pnpm 的依赖结构导致的如果放弃 symlink 这种方式会不会奏效。结果还真的行虽然这不是我想要的解决方式因为这样是完全放弃了 pnpm 的重要优势。
具体做法
在 .npmrc 文件中配置node-linkerhoisted删除 node_modules 和 pnpm-lock.yamlpnpm i 重新构建依赖 相关链接node-linker。
解决方法2依赖提层级 paths 配置
在使用 node-linkerhoisted 后我仍然不死心还是希望能够找到一个更好的方法能解决问题的同时兼顾 pnpm symlink 的重要特性。
说来也是缘分前几天一位圈内好友也遇到了类似问题并且看到了我在 TypeScript issue 中的 comment就找到了我讨论这个问题并分享了他的解决方案。
最终我的解决方法是将vue/shared这个包同时安装到 pnpm monorepo 项目的根级 node_modules 下。
pnpm add -Dw vue/shared再通过配置 tsconfig.json 中的 paths 配置项辅助 TypeScript 能够找到对应的依赖。
paths: {vue/shared: [./node_modules/vue/shared]
}经测试这个做法必须配置moduleResolution为Node16及以上。
这个解法涉及到的一些关键点其实在一些 issue 中也有提到不过我之前只是单独采用了 issue 中某一解决方法而没有把这些方法结合起来尝试最终导致我没有及时地解决掉这个问题。
具体过程和原因就不分析了如果有遇到相同问题的朋友希望能对你有所帮助