在Node.js CLI脚本中导入TypeScript文件运行报错如何解决
问题根源
你遇到的两次报错都是Node.js模块规范与TS编译配置不匹配导致的:
- 第一次
SyntaxError: Cannot use import statement outside a module是因为tsconfig里module设为ESNext,编译输出的是ES模块语法的代码,但Node.js默认将.js文件识别为CommonJS模块,无法识别import语法。 - 加了
"type": "module"后Node.js将所有.js识别为ES模块,解决了第一个问题,但ES模块标准强制要求相对路径导入必须带完整文件后缀,你TS代码里的import library from "../src/library"编译后没有自动补.js后缀,Node.js不会主动匹配后缀找文件,哪怕文件实际存在也会报错。
解决方案1:输出CommonJS模块(改动最小,无需调整现有导入语句)
适合不需要强制使用ES模块的场景,改完直接运行:
- 删除package.json里添加的
"type": "module"配置 - 修改
tsconfig-scripts.json里的module字段为CommonJS:
{ "compilerOptions": { "target": "ESNext", "module": "CommonJS", // 仅修改这一行即可 "outDir": "./build", "importHelpers": false, "strict": false, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "moduleResolution": "node" }, "exclude": ["test"] }
- 重新执行原命令即可正常运行:
npx tsc --project tsconfig-scripts.json; node build/scripts/test.js
解决方案2:保留ES模块规范
如果确实需要使用ES模块格式,按以下步骤调整:
- 保留package.json里的
"type": "module"配置 - 修改
tsconfig-scripts.json的两个配置项:
{ "compilerOptions": { "target": "ESNext", "module": "NodeNext", // 修改为NodeNext "moduleResolution": "NodeNext", // 修改为NodeNext "outDir": "./build", "importHelpers": false, "strict": false, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "exclude": ["test"] }
- 所有TS文件的相对路径导入都手动加
.js后缀(哪怕原文件是.ts后缀也需要写.js,这是TS适配ES模块的规定):
修改test.ts的导入语句:
import yargs from "yargs" import library from "../src/library.js" // 补充.js后缀 library(1);
- 重新编译运行即可。
额外优化建议
如果不想每次手动编译,可以直接用ts-node运行TS脚本,省去编译步骤:
安装依赖后执行npx ts-node --project tsconfig-scripts.json scripts/test.ts即可直接运行。
内容的提问来源于stack exchange,提问作者Greg Reynolds
相关产品推荐
相关产品推荐

