package.json 中的“main”和“module”与“exports”有什么区别?

End*_*ow8 31 javascript import require commonjs node.js

我正在尝试编写一个既可以是required 又可以是imported 的库。在网上找到了不同的方法,如下:

{
  "main": "mylib-cjs.js",
  "module": "mylib-esm.js"
}
Run Code Online (Sandbox Code Playgroud)

{
  "exports": {
    "import": "mylib-esm.js",
    "require": "mylib-cjs.js"
  }
}
Run Code Online (Sandbox Code Playgroud)

这两种方法的优点和缺点是什么,它们有何不同?

ada*_*ski 19

一般来说,"exports"领域取代了领域"module""module"它本身从来都不是一个官方标准,但它变得如此广泛,以至于在某种程度上它成为了事实上的标准。

请注意,如果 tsconfig设置为;"module"则 TypeScript 仍会使用该字段;有关详细信息,请参阅microsoft/TypeScript#50794 。moduleResolutionnode

当然,如果您的目标是尽可能向后兼容,那么同时定义这两者并没有什么问题。

"main"关于和之间的区别"exports",根据Node 文档

在包的package.json文件中,两个字段可以定义包的入口点:"main""exports"。这两个字段都适用于 ES 模块和 CommonJS 模块入口点。

所有版本的 Node.js 都支持该"main"字段,但其功能有限:它仅定义包的主要入口点。

"exports"提供了一种现代替代方案,允许"main"定义多个入口点、环境之间的条件入口解析支持,并防止除“导出”中定义的入口点之外的任何其他入口点。这种封装允许模块作者清楚地定义其包的公共接口。

对于针对当前支持的 Node.js 版本的新包,"exports"建议使用该字段。对于支持 Node.js 10 及更低版本的包,该"main"字段是必需的。如果同时定义了"exports"和,则该字段在受支持的 Node.js 版本中优先。"main""exports""main"

请记住,该"main"字段仍可能被其他在线工具(例如 jsDelivr)使用: https: //www.jsdelivr.com/documentation#id-publishing-packages