在Node.js+Apollo Server+Sequelize项目中添加TypeScript遇导入模块错误
解决CommonJS JS文件require导入TS文件时的SyntaxError问题
核心原因
你当前的tsconfig.json中设置了"noEmit": true,TypeScript不会将TS文件编译为Node能识别的CommonJS格式JS文件;同时直接用require加载未编译的TS文件时,Node无法解析TS里的import语法(属于ES模块规范),因此抛出错误。
解决方案
方案1:编译TS文件后导入(推荐生产环境)
- 修改tsconfig.json,关闭
noEmit并指定编译输出目录:
{ "compilerOptions": { // 保留其他原有配置 "noEmit": false, "outDir": "./dist" // 指定编译后的JS文件输出目录 }, "exclude": ["node_modules"], "include": ["src"] }
- 编译TS文件:
运行TypeScript编译命令(确保已安装typescript依赖):
tsc
编译后TS文件会被转译为CommonJS格式的JS文件,存放在dist目录下。
3. 在JS文件中导入编译后的JS文件:
比如你的TS文件是src/hello.ts,编译后为dist/hello.js,JS文件中这样导入:
const hello = require('./dist/hello');
方案2:用工具直接运行混合代码(适合开发环境)
如果不想每次修改TS都手动编译,可使用tsx让Node直接解析TS文件:
- 安装依赖:
npm install -D tsx
- 用tsx启动项目:
假设入口JS文件是src/index.js,运行:
npx tsx src/index.js
tsx会实时将TS文件编译为CommonJS格式(匹配你的tsconfig中module: commonjs配置),JS文件用require导入TS文件时就不会报错。
额外注意事项
- 确保
package.json中没有设置"type": "module",否则Node会将所有.js文件视为ES模块,require语法会失效。若必须设置"type": "module",需将原有JS文件重命名为.cjs后缀。 - 若TS文件使用默认导出:
// src/hello.ts export default function hello() { console.log('Hello'); }
在JS文件中导入时,得益于esModuleInterop: true配置,可直接写:
const hello = require('./dist/hello').default; // 或直接写 const hello = require('./dist/hello');
内容的提问来源于stack exchange,提问作者Gregg
相关产品推荐
相关产品推荐

