如何在ESM TypeScript项目中使用.cts扩展名?模块混用报错求助
混用ES模块与CommonJS的配置问题排查与解决
错误原因
你遇到的错误来自commonjs.cts文件:
/typescript-esm/esm-with-cts/src/commonjs.cts:1
import path from 'node:path';
^^^^^^SyntaxError: Cannot use import statement outside a module
核心问题是:.cts是Node.js官方定义的CommonJS模块专用后缀,Node.js会强制以CommonJS规则解析该文件,而你在里面使用了ESM的import语法,自然触发语法错误。
解决方法
1. 匹配文件后缀与语法风格
- 若要使用ESM的
import语法:将文件后缀从.cts改为.mts(TypeScript专属ESM模块后缀),Node.js会自动识别为ESM模块,支持import/export语法。 - 若要保持CommonJS模块:将ESM语法改为CommonJS写法:
const path = require('node:path');
2. 调整TypeScript配置
修改tsconfig.json的关键配置,让TS适配Node.js的原生模块规则:
{ "compilerOptions": { "module": "NodeNext", // 启用Node.js原生模块系统支持 "moduleResolution": "NodeNext", // 和module保持一致,确保解析逻辑匹配 "target": "ES2020", "allowSyntheticDefaultImports": true, // 方便ESM导入CommonJS的默认导出 "outDir": "./dist" } }
3. 同步package.json配置
- 如果项目根目录的
package.json设置了"type": "module",则所有.ts/.js文件默认是ESM,仅.cts/.cjs为CommonJS; - 如果未设置
"type",则默认所有.ts/.js为CommonJS,仅.mts/.mjs为ESM。
确保该配置和你的文件后缀逻辑一致。
额外提示
- TS编译后会自动转换后缀:
.mts→.mjs,.cts→.cjs,Node.js能正确识别这些编译后的文件类型; - 跨模块导入时,若遇到类型报错,确保已安装
@types/node包以获得完整的Node.js类型定义。
内容的提问来源于stack exchange,提问作者Marshmellow1328
相关产品推荐
相关产品推荐

