TypeScript项目转为ESM后构建报错,需逐个修改导入方式吗?
ESM模式下TypeScript模块命名导出报错的原因及解决方案
报错原因
- TypeScript核心包本身是CommonJS模块,它的导出是通过
module.exports挂载属性实现的,并非ESM标准的export语法定义的命名导出。 - 当你用
NODE_OPTIONS='--loader ts-node/esm' gulp build强制切换到ESM环境后,Node.js的ESM加载器会严格按照ESM规则解析模块:它会尝试从模块的明确命名导出中查找isNoSubstitutionTemplateLiteral,但CommonJS模块并没有在导出时声明这些命名项,只是把它们作为exports对象的属性存在,因此加载器识别不到,抛出找不到命名导出的错误。
解决方案(无需逐个修改导入风格)
使用默认导入后解构:将原来的命名导入改为先默认导入整个TypeScript模块,再从模块对象上解构需要的属性。比如:
// 原代码 import { isNoSubstitutionTemplateLiteral } from 'typescript'; // 修改后 import ts from 'typescript'; const { isNoSubstitutionTemplateLiteral } = ts;这种方式绕开了ESM对命名导出的严格校验,直接从CommonJS模块的默认导出(即整个
exports对象)中获取属性。配置TypeScript自动兼容:在项目的
tsconfig.json中开启以下两个配置:{ "compilerOptions": { "esModuleInterop": true, "allowSyntheticDefaultImports": true } }esModuleInterop会让TypeScript在编译时自动将CommonJS模块的命名导入转换为兼容的默认导入逻辑,allowSyntheticDefaultImports允许你使用默认导入语法导入没有默认导出的CommonJS模块,这样无需手动修改现有导入代码,就能在ESM环境下正常运行。校验Gulp插件兼容性:如果报错是来自Gulp处理TypeScript的插件(比如
gulp-typescript),需要确认插件是否支持ESM模式。如果插件本身是CommonJS的,可能需要升级到支持ESM的版本,或者在Gulpfile中使用CommonJS语法(避免强制切换ESM)。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

