ts-node:Cannot use import statement outside a module & Unknown file extension _.ts_ for xxx.ts

文章讲述了在使用ts-node时,由于环境设置(CommonJSvsESM)不匹配导致的.js和.ts文件导入错误。解决方法包括在package.json中正确设置type(node环境用commonjs,ts-node用commonjs或不设),以及在tsconfig.json中管理module选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

背景

使用 ts-node 时,出现上述错误:

  • ts-node test.ts
import { isValid } from './validParentheses';

// 有效的括号
const s = "{[";
const res2 = isValid(s);

console.log('res', res2);

原因

模块导入方式和环境要求的导入方式不匹配。

具体场景要分 js 和 ts。

js:node

// b.js
export function fn() { console.log('b') }


// a.js
import { fn } from "./b.js";
fn();

执行:node a.js,就会报上述错误。

因为 node 环境默认为 CommonJS,ESM 导入就会有这错误。

那怎么设置当前环境的模块化方式呢?

// package.json
{
  "type": "module",
}

另外:b.js 的后缀不能省略。

当然也可以将 b.js 后缀改为 b.mjs,但生产环境不建议这么使用。

ts:ts-node

Unknown file extension “.ts” for xxx.ts

如果是 ts 文件,还可能出现这个错误:Unknown file extension ".ts" for xxx.ts

什么时候出现这个错误?
当使用 ESM 导入,并且 type 设为 module 的时候。

这很奇怪啊?ESM 导入,然后 type 设为 module 那不是天经地义吗,欺负老实人?

  • 原因在于 ts-node 执行的时候,它是先编译成 CommonJS 模块的 js 文件,然后用 node 执行 js 文件的。

对于 ts-node 来说 import 就像个标记符号,没有实际功能。

所以使用 ts-node,import 导入文件可以不写后缀。

本来 node 也是这么认为的,前面已经了解了 node 无法识别 import 会报:Cannot use import ...
但现在 type 设为 module,node 就能识别 ESM 了,import 语句就有实际功能了,但 node 无法 ts 文件啊。这就像执行 node ikun.mp4一样,所以报了未知文件错误。

因此使用 ts-node ,package.json 不能将 type 设为 module,反倒应设为 commonjs,或者干脆没有 type 字段。

tsconfig.json

我的 test.ts 文件是 ESM 导入,也没有 type 字段,怎么还报Cannot use import ...

原因是一样的,依旧是环境不匹配。
对于 ts ,别忘了还有一个限制环境的文件:tsconfig.json。它的编译选项里面也有一个控制模块化的字段 module。

{
    "compilerOptions": {
        "module": "ESNext",
    },
    "include": ["src/"],
}

module 设为 ESM 后,ts-node 编译成的 js 文件是 esm 模块化标准。但 ts-node 里面的 node 执行时依旧是以 commonjs 标准执行的。这就回到了前文 js 章节的情况,自然会报错。

因此解决办法就是将 module 设为 CommonJS,或者也干脆删掉 module 字段。

有一种情况无法省略,当你使用了第三库的时候。
比如使用了 vitest,如果省略 module 字段,会对 ESM导入的 vitest 无法识别。这时显示设置为 CommonJS 即可。
在这里插入图片描述

解决办法

node & ts-node 执行 js & ts文件的模块化问题:

js

  • package.json:type设为 module

ts

  • package.json:type 设为 commonjs 或省略
  • tsconfig.json:module 设为 CommonJS 或省略,引入第三库时不能省略。

另外 ts-node 默认可以直接使用 esm 模块导入,所以简单使用时, package.json、tsconfig.json 这些文件反倒碍事,不要它们直接用就完了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值