2

我正在将我的反应组件库react-esri-leaflet转换为打字稿。该库要求用户安装 react-leaflet 作为 peerDependency,它提供对 react-leaflet 版本 3 (RLV3) 和 react-leaflet 版本 2 (RLV2) 的支持。对于默认组件,我可以简单地做

import { createLayerComponent } from 'react-leaflet'

但是如果用户想要使用与 RLV2 兼容的组件,他们可以单独导入这些组件(请随意查看库文档以了解如何使用)。大多数 RLV2 组件都以类似的开头

import { withLeaflet, MapControl } from 'react-leaflet'

在转换为打字稿时,这会引发错误。在开发这个库时,我安装的 react-leaflet 安装了最新版本。withLeaflet并且MapControl不再存在于该版本中。

为了解决这个问题,我遵循了“Node 应用程序中相同 npm 包的两个版本”的答案中的建议。这使我可以通过将 RLV2 别名为 来将 RLV2 视为源代码中的一个单独的包,'react-leaflet-v2'我可以这样做

import { withLeaflet, MapControl } from 'react-leaflet-v2'

太好了,现在打字稿很高兴,我可以将适当版本的 react-leaflet 导入适当的组件,并且打字是正确的。但是,当我使用 编译回 js 时tsc,我的 V2 组件中使用的包名称仍然是'react-leaflet-v2'.

问题是该库的最终用户将使用RLV2或 RLV3,并且将'react-leaflet'在他们的项目中简单地调用它。库的编译文件需要能够找到'react-leaflet',而不是某个别名,无论它们使用的是什么版本。

如何在两个依赖版本的开发中保持类型安全,但让我的用户不用担心,这意味着只需安装他们想要使用的 react-leaflet 版本,从库中导入正确的组件,并拥有组件在他们的项目中找到'react-leaflet'依赖项?编译时是否可以告诉tsc重命名?还有其他解决方案吗?'react-leaflet-v2''react-leaflet'

4

1 回答 1

0

于是我想出了一个办法。它并不完美,但基本上:

使用通天塔

我没有使用 ts 转换我的 ts 文件tsc,而是使用了 babel,仅用于那些具有别名节点模块导入的文件。我找到了babel-plugin-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 和 whistles。如您所见,它将所有从“react-leaflet-v2”的导入重命名为“react-leaflet”。

考虑到我的项目被组织为将所有这些 RLV2 文件放在它们自己的文件夹中,我编写了一个脚本来使用常规tsc命令编译所有常规组件,但使用带有该配置的 babel 仅转换 v2 目录中的文件。然后我使用 atsc --emitDeclarationOnly true来编写.d.tsv2 文件的文件。

请注意,这很有效,因为我的库没有从“react-leaflet-v2”导入任何纯打字稿声明,这意味着不import { TypeOrInterfaceOrEnum } from 'react-leaflet-v2'——所有导入都只是组件或函数。import something from 'react-leaflet-v2'如果我从 react-leaflet-v2 导入了类型信息,我的文件中仍然会存在.d.ts,我还需要以某种方式对其进行转换。也许 babel 也可以这样做,但我现在没有必要探索它。

于 2021-04-23T21:30:07.433 回答