为什么 TypeScript 看不到包的导出? (使用模块:CommonJS 和 moduleResolution:Node)

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

我在包根目录的 dist 文件夹中有为 ESM 和 CJS 格式构建的 NPM 包

  • dist/esm - 带 ESM 的模块
  • dist/cjs - 带有 CJS 的模块
  • dist/types - 所有模块的类型

package.json 中还有导出字段,例如:

{
  "exports": {
    "./foo": {
      "types": "./dist/types/foo.d.ts",
      "require": "./dist/cjs/foo.js",
      "import": "./dist/esm/foo.js",
      "default": "./dist/esm/foo.js"
    },
    "./bar": {
      "types": "./dist/types/bar/index.d.ts",
      "require": "./dist/cjs/bar/index.js",
      "import": "./dist/esm/bar/index.js",
      "default": "./dist/esm/bar/index.js"
    },
    "./hello/world": {
      "types": "./dist/types/hello/world/index.d.ts",
      "require": "./dist/cjs/hello/world/index.js",
      "import": "./dist/esm/hello/world/index.js",
      "default": "./dist/esm/hello/world/index.js"
    }
  }
}

如您所见,foo 是 foo.js 的别名,但 bar 是 bar/index.js 的别名

我在其他带有 TypeScript 的项目中使用这个包,tsc 看不到 bar 和 hello/world

它只看到 foo

import foo from 'my-pkg/foo' // WORKS FINE 
import bar from 'my-pkg/bar'; // NOT WORKING (cannot find declarations for...)
import helloWorld from 'my-pkg/hello/world'; // NOT WORKING (cannot find declarations for...)

为什么会这样?

在没有 TypeScript 的 Node.js 中,它可以在 ESM 和 CJS 中正常工作,没有错误。

只有 TypeScript 找不到类型定义

javascript node.js typescript npm package.json
1个回答
0
投票

这可能无法回答您的问题,但对于您想要完成的任务很重要,并且对于评论来说太长了。

这不会像你实现的那样工作,至少在我写这篇文章的时候不会。这很难做到,所以不要感到难过。现在我向你展示兔子洞有多深......

当您没有

exports
地图节点时,将尊重您的package.json中的
main
module
条目,并会根据
.js
文件是否为
import
以正确的方式处理它们ed 或
require
d,只要您
type
设置为“模块”。

但是,一旦添加

exports
映射,它就会优先,并且 所有 .js 文件将被视为 CJS 或 ESM,具体取决于您在 package.json 中设置
type
的内容,无论它是否是
 
import
地图
中的require
exports
路径。所以这给了你三个选择:

  1. 不要使用
    exports
    映射,将
    type
    设置为“commonjs”(或省略它)并使用
    module
    属性指向您的 ESM 入口点。
  2. 将所有 esm 文件更改为 .mjs(并将 .mjs 添加到所有导入中)
  3. 将所有 cjs 文件更改为 .cjs(并将 .cjs 添加到您的所有需求中)

选项#2和#3的问题是Typescript编译器不会为你添加它,并且他们一再拒绝实现这个

值得注意的是,尽管规范规定 ESM 导入的扩展名应该是“.js”,但实际上几乎所有最新的工具(例如 Typescript、Rollup、Webpack、Vite)和最新的引擎(例如 V8、Webkit)将接受“.mjs”。

您可以使用 shell 脚本破解它,将文件扩展名替换为

find
/
mv
sed
将文件扩展名附加到导入语句上,您可以通过使用真正的解析器来轻松完成此操作达到相同的结果,或者您可以使用像 this package 这样的东西来为您做到这一点。

如果您想查看这一切的实际效果,请参阅我在 GitHub 上写的 示例。

祝你好运!

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