前情提要:从ts-node报错发现了大坑

彼时我正在开发一个内网npm包,用于在开发时生成TS接口类型。

该包中的代码(以及生成的代码,因为生成的代码为纯类型声明)并不会在浏览器环境中运行,也不会包含在产物中,因此可以看作是纯Node工具

在开发时,我尝试使用ts-node进行调试,但出现了以下错误:

image.png

当时的我很疑惑,明明是ts-node为何会不支持.ts的拓展名呢?

经查阅,我发现ts-node的运行过程其实是先使用tsc编译成JS后再使用Node运行,在过程中会读取项目的tsconfig.json中的配置项。

因此,只需要分别运行tsc编译和node执行两个阶段就可以找出到底在哪里出了问题。

尝试复现问题

我尝试新建一个最简单的环境来复现问题本身:

  1. 使用npm init新建一个npm项目,安装typescript和ts-node两个包
  2. 编写index.tsmoduleA.ts两个文件模拟模块导入导出
  3. 使用tsc编译并使用Node执行
// moduleA.ts
export const a = "this is moduleA";

// index.ts
import { a } from "./moduleA";

console.log(a);

使用tsc编译后单独执行和直接使用ts-node都正常,运行效果是一样的:

image.png

package.json中设置type: module后(指定全局为ESM模块),运行ts-node出现了和上面一样的报错:

image.png

而单独使用tsc+node运行报错则不一样,提示为模块类型不兼容(在ESM模块中使用了CJS语法):

image.png