我正在将我的react组件库react esri传单转换为typescript。该库要求用户将react传单作为peerDependency安装,并提供对react传单版本3(RLV3(和react传单版2(RLV2(的支持。对于默认组件,我可以简单地进行
import { createLayerComponent } from 'react-leaflet'
但是,如果用户想使用与RLV2兼容的组件,他们可以单独导入这些组件(可以查看库文档了解如何导入(。大多数RLV2组件都是从类似的东西开始的
import { withLeaflet, MapControl } from 'react-leaflet'
在转换为typescript时,这会引发一个错误。在开发这个库时,我安装的react传单安装了最新版本。CCD_ 1和CCD_。
为了解决这个问题,我遵循了这个答案中的建议:;节点应用程序中相同npm包的两个版本";。这允许我在源代码中将RLV2作为一个单独的包处理,将其别名为'react-leaflet-v2'
,并且我可以进行
import { withLeaflet, MapControl } from 'react-leaflet-v2'
很好,现在打字很好,我可以将适当版本的react传单导入到适当的组件中,并且打字正确。但是,当我使用tsc
编译回js时,V2组件中使用的包名称仍然是'react-leaflet-v2'
。
问题是,库的最终用户将使用RLV2或RLV3,在他们的项目中,它将被简单地称为'react-leaflet'
。库的编译文件需要能够找到'react-leaflet'
,而不是一些别名,无论它们使用的是什么版本。
我如何在两个依赖版本的开发中维护类型安全,但让我的用户不用担心,也就是说,只需安装他们想要使用的react传单版本,从库中导入正确的组件,并让组件在其项目中找到'react-leaflet'
依赖项?编译时是否可以告诉tsc
将withLeaflet
0重命名为'react-leaflet'
?还有其他解决方案吗?
所以我找到了一个方法。它并不完美,但基本上:
使用Babel
我没有使用tsc
来传输ts文件,而是使用babel,只用于那些具有别名节点模块导入的文件。我发现了babel插件transform-rename-import,它可以在编译时重命名导入。将其添加到标准的babel配置中,我得到了以下内容:
{
"presets": ["@babel/preset-env", "@babel/preset-typescript"],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
"transform-react-jsx",
"@babel/plugin-proposal-class-properties",
[
"transform-rename-import", // <--- solution here
{ "original": "react-leaflet-v2", "replacement": "react-leaflet" }
]
]
}
这是react typescript文件的标准设置,带有一些额外的bella和口哨。正如您所看到的,它将重命名从";react-leaflet-v2";至";反应传单";。
考虑到我的项目被组织为将所有这些RLV2文件都放在自己的文件夹中,我编写了一个脚本,使用常规tsc
命令编译所有常规组件,但使用babel和该配置只转换v2目录中的文件。然后,我使用tsc --emitDeclarationOnly true
为v2文件编写.d.ts
文件。
注意,这很好,因为我的库没有从"react-leaflet-v2"导入任何纯类型脚本声明,这意味着没有import { TypeOrInterfaceOrEnum } from 'react-leaflet-v2'
——所有导入都只是组件或函数。如果我从react-leaflet-v2导入了类型信息,那么在我的.d.ts
文件中仍然会有import something from 'react-leaflet-v2'
,我也需要以某种方式转换这些信息。也许巴贝尔也能做到,但我现在没有必要去探索它。