浏览器和node.js中使用的库的哪些typescript模块设置

问题描述 投票:0回答:1

有很多关于这方面的资源,但很容易令人困惑,我找不到任何关于这方面的最新资源:

2024 年的今天,我想创建一个用 tyescript 编写的库。 它将用于使用 webpack 捆绑器的 React 项目。该应用程序将在服务器(node.js)和浏览器中呈现。

如何配置 tsconfig.json?我该选择哪个设置

module

背景:

该库已经存在于 CJS 中,但在当前的大重写中,我正在考虑升级到 ESM,因为我们使用该库(目前也是 CJS)的应用程序在导入仅 ESM 模块时存在问题。而且,使用 CJS,在 webpack 中使用动态导入时,我们无法使用自动分割包。

文档

module

的打字稿参考指出
es2015
es2020
es2022
esnext
不应用于node.js

它指出

node16 和 nodenext 是所有打算在 Node.js v12 或更高版本中运行的应用程序和库的唯一正确的模块选项

但没有提及

nodenext
node16
是否也可以用于像 webpack 这样的浏览器/捆绑器。

这是什么?我应该选择哪个?

我想知道是否应该分开发布

/lib/cjs
/lib/esm
版本,并在
require
module
设置中包含
export
package.json
字段?

这仍然给我留下了一个问题:在 tsconfig 中使用哪个

module
输出设置,以便浏览器(通过 webpack)和 node.js 都可以使用 ESM。或者我应该选择其中一种环境来继续使用 CJS?

node.js typescript webpack es6-modules
1个回答
0
投票

由于历史原因,组合太多,但大部分已经不需要了。总而言之,如果您想发布 Node.js 和浏览器都可以使用的仅 ESM 包,以下三个规则就足够了:

  • 您的包应该使用
    "type": "module'
  • 如果您为 Node.js 编写库,那么:
    • "module": "NodeNext"
    • "moduleResolution": "NodeNext"
  • 如果您正在通过 bundler only 为前端创作库,那么:
    • "module": "ESNext"
    • "moduleResolution": "Bundler"

最后,还有一个公理 -

NodeNext + NodeNext
的组合是
ESNext + Bundler
的子集。另一种说法是,
NodeNext + NodeNext
是具有由 Node.js 模块解析算法设置的约束的 ESM。最常见的例子是在导入语句中强制要求具有文件扩展名,例如
import {} from 'other.js'
NodeNext + NodeNext
。此限制不适用于
ESNext + Bundler
模式。

因此,如果您同时发布 Node.js(希望在不捆绑的情况下使用)和前端(希望使用

import-maps
或捆绑器),那么您应该使用
module: NodeNext + moduleResolution: NodeNext

这确保了 TypeScript(和其他现代捆绑器)遵循

main
规范
指定的
exports
package.json声明。

此外,请记住

"type": "module"
很重要。如果没有,即使有
module: NodeNext
,打字稿编译器也会使用 CJS
*.ts
语句将
*.js
文件编译为
require
,并使用 ESM import 语句将
*.mts
文件编译为
*.mjs

最后,还有另一种思考方式!如果您使用 TypeScript 作为编译器来编译您的库,那么您应该使用

NodeNext + NodeNext
。而且,如果您使用的是捆绑器,那么您可以选择任一组合(尽管我仍然建议使用
NodeNext + NodeNext
,因为它引入了严格的语义)。

© www.soinside.com 2019 - 2024. All rights reserved.