如果在TypeScript项目的依赖项中混合了tsconfig“targets”和“libs”,会发生什么情况?

juzqafwq  于 2023-02-20  发布在  TypeScript
关注(0)|答案(1)|浏览(195)

我正在构建一个电子应用程序,导入一个名为foo的模块,该模块导入一个名为bar的模块。
从历史上看(但没有任何原因),所有三个项目在其tsconfig.json中都有不同的target和lib值。
电子应用程序tsconfig.json

"target": "es5",
"lib": ["es2017", "es2016", "es2015", "dom"]

节点模块/foo tsconfig.json

"target": "es2021",
"lib": ["es2019", "es2016", "es2015"]

节点_模块/栏tsconfig.json

"target": "es2017",
"lib": ["es2015"]
    • 问题**:给定一个TypeScript项目,它的targetlib值对其文件的迁移以及依赖于它的其他项目的文件的迁移有什么影响?依赖项及其依赖项之间的混合值可能会发生什么类型的问题?

下面是一个具体的例子,可以用于说明目的:我是否可以将node_modules/bar设置为目标"es2022",并在以"es6"为目标的Electron项目中使用它?
顺便说一句:在lib中列出更多条目是否有利?

hrysbysz

hrysbysz1#

target设置决定了JS * 语言 * 结构(非标准JS API)如何降级。即来自较新JS语言标准的语法糖可以降级,但一般来说,TS编译器不会/不能降级旧ECMA脚本标准中不存在的JS API的使用(例如Promise.allArray.prototype.includes)。
lib设置决定了标准JS API/builtin * libraries *(例如DOM)的哪个版本应该在代码运行的环境中可用。也就是说,符合所选标准的JS API将使其类型可用,而使用那些不可用的类型将触发编译器警告。
注:你不需要同时指定多个ES库。2只需要指定你期望能够使用的最新的库,以及来自较新版本的任何所需的子部分就足够了(例如es2015, es2017.String)。通过列出multiple,您将告诉TS编译器为多个JSAPI版本引入作用域类型。我想不出会发生什么不好的结果,但我也想不出会发生什么好事,我宁愿打赌,有人能想到会发生什么坏事(而不是好事)。

    • 每个项目/包都是独立地从TS编译到JS****。编译项目/包时,不编译依赖项(依赖项单独编译),TS编译器使用该项目/包的tsconfig.json中的设置来编译它。

以下是一些启示:

  • 如果一个项目依赖于另一个包,而该包为比它选择的target更新的target发出了JS,则该项目不应期望事情正常工作
  • 也就是说,依赖项可能使用的语言结构对于它选择的target不需要降级,但是对于使用较低目标的依赖包需要进一步降级。
  • 如果一个项目依赖于另一个使用比它所选择的更新的lib(即更新的标准JS API)的包,那么它不应该期望事情仅仅工作。
  • 即,依赖项可能期望在比依赖项期望在其上运行的环境更新的环境上运行。

在这两种情况下,从技术上讲,问题都是依赖项的问题,并且可以观察到依赖项没有按预期工作,或者在依赖项打算支持的某些较旧环境中出错。有两种方法可以避免/减轻这种情况的发生:

  • 在依赖端(使用依赖关系的端):
  • 在可能的情况下,为依赖项希望能够使用但不希望存在于部署环境中的JS API添加polyfills
  • 工具可以被插入到项目的构建系统中,将依赖项与项目自己的代码捆绑在一起,并进行另一次降级(除了TS编译器根据每个项目不同的tsconfig设置 * 分别 * 为每个项目进行的降级)。例如,使用一些WebPack + Babel设置。
  • 在库作者端:
  • 许多使用TS源代码的流行库选择保守的targetlib值,例如ES6(ES2015),在撰写本文时为is very well supported。他们这样做是为了增加他们的库与依赖库兼容的机会。

也就是说,Foo对Bar的使用是可以的(targetlib在Foo中的使用率都高于Bar),但电子应用程序对Foo的使用率却不是。
我不认为TS编译器会警告你,如果你在这方面犯了错误,因为在编译之后,tsconfig通常不会和包一起分发。也就是说,TS编译器没有办法获得关于包的信息。但是正如已经讨论过的,你不应该这样做。在TS工具和生态系统中,这方面可能还有改进的空间,但是出于某种原因,目前的情况被认为是正常的/可接受的--也许是因为许多流行的库努力避免语言特性和JSAPI,这些特性和API还没有得到非常广泛的支持。

相关问题