关于 pnpm monorepo 项目中 TS2742 Error 的 workaround

2024-06-23 22:44

本文主要是介绍关于 pnpm monorepo 项目中 TS2742 Error 的 workaround,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近我在使用 pnpm 作为包管理器开发一个 monorepo 项目,从个人体验来说,在 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/@vue+runtime-core@3.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 上一些关联度很高的 issue,issue 来源包括 typescript, pnpm 等仓库。

microsoft/TypeScript#42873

microsoft/TypeScript#47663

这些 issue 在21年,22年就提出了,但是目前也还没有 Close。我试了 issue 讨论中提到的一些方法,包括修改preserveSymlinks,在项目根目录安装对应依赖,设置 tsconfig.json 中的paths配置辅助 TypeScript 找到对应依赖的位置等,但是最后都没有奏效,可能是我的解决姿势不正确,最终困扰了几天,在 google, stackoverflow, github 上一无所获,也尝试过 debug 去分析代码执行过程,也没看明白。

解决方法1:node-linker=hoisted

于是我在想是不是 pnpm 的依赖结构导致的,如果放弃 symlink 这种方式会不会奏效。结果还真的行,虽然这不是我想要的解决方式,因为这样是完全放弃了 pnpm 的重要优势。

具体做法:

  1. 在 .npmrc 文件中配置node-linker=hoisted
  2. 删除 node_modules 和 pnpm-lock.yaml
  3. pnpm i 重新构建依赖

pnpm

相关链接:node-linker。

解决方法2:依赖提层级 + paths 配置

在使用 node-linker=hoisted 后,我仍然不死心,还是希望能够找到一个更好的方法,能解决问题的同时兼顾 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"]
}

经测试,这个做法必须配置moduleResolutionNode16及以上。

这个解法涉及到的一些关键点其实在一些 issue 中也有提到,不过我之前只是单独采用了 issue 中某一解决方法,而没有把这些方法结合起来尝试,最终导致我没有及时地解决掉这个问题。

具体过程和原因就不分析了,如果有遇到相同问题的朋友,希望能对你有所帮助!

这篇关于关于 pnpm monorepo 项目中 TS2742 Error 的 workaround的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088485

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

SpringBoot项目是如何启动

启动步骤 概念 运行main方法,初始化SpringApplication 从spring.factories读取listener ApplicationContentInitializer运行run方法读取环境变量,配置信息创建SpringApplication上下文预初始化上下文,将启动类作为配置类进行读取调用 refresh 加载 IOC容器,加载所有的自动配置类,创建容器在这个过程

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

2. 下载rknn-toolkit2项目

官网链接: https://github.com/airockchip/rknn-toolkit2 安装好git:[[1. Git的安装]] 下载项目: git clone https://github.com/airockchip/rknn-toolkit2.git 或者直接去github下载压缩文件,解压即可。

9.8javaweb项目总结

1.主界面用户信息显示 登录成功后,将用户信息存储在记录在 localStorage中,然后进入界面之前通过js来渲染主界面 存储用户信息 将用户信息渲染在主界面上,并且头像设置跳转,到个人资料界面 这里数据库中还没有设置相关信息 2.模糊查找 检测输入框是否有变更,有的话调用方法,进行查找 发送检测请求,然后接收的时候设置最多显示四个类似的搜索结果

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd