Next.js项目tsconfig设module为esnext时ts-node无法编译TS文件如何解决
Next.js+TypeScript 项目 ts-node 运行 ES 模块编译失败解决方案
根本原因
- ts-node 默认使用 CommonJS 模式加载文件,当 tsconfig 中
module设为esnext时,TypeScript 编译输出的是 ES 模块语法的代码,Node.js 原生 CommonJS 加载器无法识别import语句,就会抛出「Cannot use import statement outside a module」错误。 - 当你在 package.json 中添加
"type": "module"后,Node.js 会默认使用 ES 模块加载器,但原生加载器不识别.ts后缀的文件,你也没有开启 ts-node 的 ES 模块支持,所以会抛出「Unknown file extension ".ts"」错误。
解决方案(全程保留ES模块规范,无需降级CommonJS)
前置要求
确保本地安装的 ts-node 版本≥10.0.0,旧版本对ES模块的支持不完善。
操作步骤
- 在 package.json 中添加配置项
"type": "module",告知 Node.js 项目默认使用 ES 模块规范。 - 修改 tsconfig.json 配置,新增
ts-node专属配置段,同时调整模块相关配置:
{ "compilerOptions": { "target": "ES2021", "module": "esnext", "moduleResolution": "node16", // 新增/修改为node16,适配ES模块解析规则 "baseUrl": ".", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, "noImplicitAny": true, "strictNullChecks": true, "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve" }, // 新增ts-node专属配置 "ts-node": { "esm": true, "experimentalSpecifierResolution": "node" }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", "**/[*].ts", "**/[*].tsx", ], "exclude": ["node_modules"] }
- 调整代码中的相对导入路径,ES 模块规范要求相对导入必须补全后缀名,比如你
seeder.ts中导入 User 接口的语句:
原代码:import { User } from "../interfaces/user";
修改为:import { User } from "../interfaces/user.js";
(TypeScript 会自动识别对应.d.ts文件,无需担心后缀写错) - 运行脚本时添加
--esm参数(配置了上面的ts-node规则后也可以不加,建议加上保证兼容性):
npx ts-node --esm helpers/seeder.ts
可选方案(不改全局package.json的type配置)
如果你不想让整个项目默认走 ES 模块规范,只需要单独给要执行的 ts 脚本改后缀为 .mts,然后运行命令时加 --esm 参数即可,无需修改 package.json 的 type 配置。
内容的提问来源于stack exchange,提问作者nhasanli
相关产品推荐
相关产品推荐

