How can I use "exports" in package.json for nested submodules and TypeScript?

Rya*_*ale 30 javascript node.js npm typescript

I want to take advantage of the new-ish "exports" feature of Node.js/package.json so that I can do the following:

"exports": {
  ".": "./dist/index.js",
  "./foo": "./dist/path/to/foo.js"
}
Run Code Online (Sandbox Code Playgroud)

and users can do the following:

import { foo } from 'my-package/foo';
Run Code Online (Sandbox Code Playgroud)

TypeScript 4.5 should support the "exports" field, yet it does not seem to work. I am building a simple package using TS 4.5.2, and I am consuming that package in a project using TS 4.5.2. I have looked at other SO questions and this GitHub thread and this bug report but can't seem to find a consensus on the issue and whether it should work today.

I am still able to import using the more verbose syntax:

import { foo } from 'my-package/dist/path/to/foo.js';
Run Code Online (Sandbox Code Playgroud)

I have also tried the object notation for exports, to no avail:

"exports": {
  ".": { "require": "./dist/index.js", "import": "./dist/index.js" },
  "./foo": { "require": "./dist/path/to/foo.js", "import": "./dist/path/to/foo.js" }
}
Run Code Online (Sandbox Code Playgroud)

Is this feature ready to be used with TypeScript projects today? If yes, what am I missing? Specifics about tsconfig would be useful for both the source project and consuming project. The TS compiler complains about node12/nodenext being used for either the module or moduleResolution fields (I am definitely using TS 4.5.2).

Rya*_*ale 22

  • exportsNode.js自 v12.7.0(2019 年 7 月)起支持

    当我提出这个问题时(2021 年 12 月),NodeJS 已经支持该exports领域近 2.5 年了。假设 Typescript 支持它似乎是合理的。

  • 当时 TypeScript 的最新版本(4.5)不支持该exports领域。

    这尤其令人困惑,因为TS 4.5 beta 公告称它将支持package.json导出。

  • Typescript 4.7(2022 年 6 月)终于支持package.json导出

  • 使用typesVersionsinpackage.json不是解决方案

    有几个人建议使用typesVersions- 但这是一个完全独立的功能,仅特定于 TypeScript(在此处阅读更多相关信息)。exports中的字段是package.jsonNode 的一个功能,应该与任何 npm 模块一起使用。

因此,如果您有一个 Typescript 项目,并且希望能够导入使用 package.json“exports”的包,则需要执行以下操作:

  • 您的 TypeScript 项目必须使用 TS v4.7 或更高版本
  • tsconfig应该使用moduleResolutionofnode16nodenext
    • moduleResultion如果您使用的是、、、、 或module值,则不必设置CommonJSES2015ES6ES2020ESNEXT


And*_*ndy 8

package.json如果您使用"moduleResolution": "NodeNext"(或"Node16") 而不是广泛使用的"moduleResolution": "Node". (我猜"moduleResolution"默认值与 相同"module",但很难找到这方面的文档?

更新:在 TypeScript 5 中还有一个"moduleResolution": "bundler"也尊重导出映射的选项。两者的区别是:

  • "bundler"导入中的相对路径从不需要文件扩展名
  • "NodeNext"将匹配"node"导出映射中的导出条件,但"bundler"不会(TSConfig 参考中尚未记录...尚未找到我与 TypeScript 团队确认这一点的问题线程)

请参阅: https: //www.typescriptlang.org/docs/handbook/esm-node.htmlhttps://www.typescriptlang.org/tsconfig#moduleResolution

由于没有显式文件扩展名的相对导入等原因,许多 TS 库(包括许多 Microsoft 自己的库)"moduleResolution": "NodeNext"现在都存在错误。


GOT*_*O 0 5

在不知道您遇到什么错误,或者 TypeScript 似乎不以其他方式为您工作的情况下(不知道为什么您不想共享如此重要的信息),我可以说您的exports部分似乎缺少类型信息。通常,如果您的 .d.ts 文件位于各自的 .js 文件旁边,您的导出部分将如下所示:

"exports": {
  ".": {
    "types": "./dist/index.d.ts",
    "default": "./dist/index.js"
  },
  "./foo": {
    "types": "./dist/path/to/foo.d.ts",
    "default": "./dist/path/to/foo.js"
  }
}
Run Code Online (Sandbox Code Playgroud)