【问题标题】:Account for multiple peer dependency versions in react-typescript library在 react-typescript 库中考虑多个对等依赖版本
【发布时间】:2021-07-16 21:15:13
【问题描述】:

我正在将我的 react 组件库 react-esri-leaflet 转换为 typescript。该库要求用户安装 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 安装了最新版本。 withLeafletMapControl 在该版本中不再存在。

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

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

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

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

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

【问题讨论】:

    标签: reactjs typescript npm libraries peer-dependencies


    【解决方案1】:

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

    使用通天塔

    我没有使用tsc 转换我的 ts 文件,而是使用 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 文件的标准设置,带有一些额外的花哨和口哨。如您所见,它会将所有导入从“react-leaflet-v2”重命名为“react-leaflet”。

    考虑到我的项目被组织成将所有这些 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',我还需要以某种方式转换它们。或许 babel 也可以,不过我现在没必要去探索。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-28
      • 2017-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 1970-01-01
      相关资源
      最近更新 更多