有一个使用ESM模块的TS 4.7库.

帖子主题:Re:Колибри

    "target": "ES2020",
    "module": "ES2020",
    "lib": ["ES2020"], 
    "moduleResolution": "node",

Package.json

"type": "module",

我有一个主文件,其中只有一个愚蠢的导出:

Index.ts

export { Spig } from './spig';

它被编译为:

Index.js

export { Spig } from './spig';
//# sourceMappingURL=Index.js.map

问题

当我从Node CLI程序使用此库时(也启用了ESM模块),我收到以下错误:

Cannot find module <path>/lib/spig imported from <path>/lib/Index.js

When I manually add .js in the generated Index.js, the issue is gone:

export { Spig } from './spig.js';

我如何才能强制TypeScrip编译器也生成扩展?我错过了什么吗?

推荐答案

在ESM模块导入中不能再省略文件扩展名.对于打字文件,扩展名应始终为.js/.jsx,而不是.ts/.tsx.因此,在index.ts中,您应该将扩展名添加到spig导出,如下所示,如果使用ESM模块,则应添加导入/导出的所有其他文件:

index.ts

export { Spig } from './spig.js'; 

此外,应将moduleResolution设置为Node16NodeNext,以便ESM模块按预期工作.

docs(由我提出)所述:

相对导入路径需要完整扩展名(例如,我们必须写入import "./foo.js"而不是import "./foo").

When a 100 file is compiled as an ES module, ECMAScript import/export syntax is left alone in the 101 output;当它被编译为CommonJS模块时,它将生成与您今天在MODULE下得到的输出相同的输出:Commonjs.

这也意味着.ts个ES模块文件和CJS模块文件之间的路径解析方式不同.例如,假设您今天有以下代码:

// ./foo.ts
export function helper() {
    // ...
}

// ./bar.ts
import { helper } from "./foo"; // only works in CJS
helper();

此代码在CommonJS模块中工作,但在ES模块中会失败,因为relative import paths need to use extensions.因此,它将不得不重写以使用输出foo.ts的扩展名--因此bar.ts将不得不从./foo.js导入.

// ./bar.ts
import { helper } from "./foo.js"; // works in ESM & CJS
helper();

起初,这可能会感觉有点麻烦,但像自动导入和路径完成这样的打字工具通常会为您做这件事.

Node.js相关问答推荐

Spotify Auth访问令牌给出错误代码400

Mongoose更新许多不使用数组作为筛选器来更新记录

如何将我的Redis客户端配置为在禁用群集模式的情况下使用读取副本?

无法从 mongoDB 访问数据?

如何在 require 方法中使用路径与node.js react ?

表达 js 错误处理程序在第一个之后被忽略

Indexeddb 获取所有不同于特定值的记录

Nodejs 从链接数组中获取数据并保存到 mongodb

如何在 TypeScript 中输出 Hackerrank 二叉树问题?

如果 express.js (node.js) http 请求在完成之前关闭会发生什么?

分块 WebSocket 传输

在 Mongoose 中创建外键关系

MongoDB Node findone如何处理没有结果?

Node.js -Firebase 服务帐户私钥不会解析

什么是 JavaScript 中的REPL?

Javascript在try块内设置const变量

使用 node.js 循环 JSON

在 Node.js 中写入 CSV

Mongoose:模式与模型?

node.js 异步库