什么 TypeScript 配置产生最接近 Node.js 14 功能的输出?

Posted

技术标签:

【中文标题】什么 TypeScript 配置产生最接近 Node.js 14 功能的输出?【英文标题】:What TypeScript configuration produces output closest to Node.js 14 capabilities? 【发布时间】:2020-08-01 23:00:56 【问题描述】:

随着 Node.js 带来了对 ES2020 的更新支持并添加了对 ES 模块的支持,如何配置 TypeScript 以输出利用所有这些新功能的 javascript 代码?

【问题讨论】:

【参考方案1】:

从 Node.js 14.0.0 开始,100% 支持 ES2020,并且对 ES Modules 的支持已经落地!如果您知道您的目标是该版本或更高版本,则最佳配置如下所示:

"module": "ES2020" & "moduleResolution": "node"

Node.js 14 支持加载模块而不是旧的 CommonJS 格式,我们必须告诉 TypeScript 我们正在使用 Node.js 的规则来解析模块。

"allowSyntheticDefaultImports": true

为了提供向后兼容性,Node.js 允许您使用默认导入来导入 CommonJS 包。这个标志告诉 TypeScript 可以在 CommonJS 模块上使用 import

"target": "ES2020"

这告诉 TypeScript 可以输出带有 ES2020 特性的 JavaScript 语法。在实践中,这意味着它将例如输出可选的链接运算符和 async/await 语法,而不是嵌入 polyfill。

"lib": ["ES2020"]

这告诉 TypeScript 可以使用 ES2020 或更早版本中引入的函数和属性。在实践中,这意味着您可以使用例如Promise.allSettledBigInt

完整的配置将是:


  "compilerOptions": 
    "allowSyntheticDefaultImports": true,
    "lib": ["ES2020"],
    "module": "ES2020",
    "moduleResolution": "node",
    "target": "ES2020"
  

除此之外,我们还需要告诉 Node.js 将此项目中的.js 文件视为 ES Modules。这样做的原因是 Node.js 必须保持与为旧 Node.js 版本编写的代码的向后兼容性。这可以通过将"type": "module" 添加到您的package.json 来完成:


  "type": "module"

如果您使用的是较早版本的 Node.js,另一个变化是 the file extension when importing files are now mandatory。这意味着您必须在本地导入的末尾写出.js。请注意,这是 .js,即使您正在导入一个实际上具有文件扩展名 .ts 的 TypeScript 文件。这可能看起来有点令人困惑,但this comment from one of the TS contributors explains why that is。

以下是一些如何编写import 语句的示例:

// Built-in Node.js modules
import  readFileSync  from 'fs'

// CommonJS packages from Npm
import md5File from 'md5-file'

// The local file "a.ts"
import  a  from './a.js'

如果你现在想坚持使用 CommonJS,为了避免上面解释的警告,你可以使用以下配置:


  "compilerOptions": 
    "lib": ["ES2020"],
    "module": "CommonJS",
    "target": "ES2020"
  


如果你运行的是 Node.js 16,你可以看到我的similar answer for Node.js 16 here

如果你运行的是 Node.js 12,你可以看到我的similar answer for Node.js 12 here

如果你运行的是 Node.js 10,你可以看到我的similar answer for Node.js 10 here

如果你运行的是 Node.js 8,你可以看到我的similar answer for Node.js 8 here

【讨论】:

有一种方法可以在导入时省略 .js 扩展名,我在 modern-typescript-project 存储库中记录了这一点。除此之外,感谢您推动使用 TypeScript 生成 ES 模块代码!让我们希望 TypeScript 模块作者开始采用这个和publish proper ES Modules。 @DanDascalescu 是的,我正在讨论是否要包含 --experimental-specifier-resolution=node,但最终决定不包含,因为我不想让太多人开始使用 --experimental-* 标志。感谢您的链接! :) esModuleInterop 呢?我推断它可以或必须为假,因为您明确设置allowSyntheticDefaultImports @Gili 此配置使用新引入的(对 Node.js)ES 模块,而您链接的那个则坚持使用 CommonJS。我个人会推荐这个,因为我认为 ES 模块是未来...... 这正是我一直在寻找的,感谢您领先Microsoft。

以上是关于什么 TypeScript 配置产生最接近 Node.js 14 功能的输出?的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1278 相离的圆 二分

python 中最接近 WordPress 而不是 php 的东西是啥? [关闭]

什么 AsyncGenerator TypeScript 类型会产生 Promise?

初识Typescript

或许是网上最详细从零开始配置 TypeScript 项目的教程

51nod 1061 最复杂的数V2