You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TS项目引入file-type触发ERR_REQUIRE_ESM错误的技术求助

解决CommonJS项目引入原生ESM包file-type的模块冲突问题

错误原因

file-type从v18版本开始完全切换为原生ESM包,不再支持CommonJS的require()导入方式。而你的TypeScript项目编译目标是CommonJS("module": "commonjs"),编译后的代码会用require()去加载file-type,触发Node.js的ESM/CommonJS互斥错误。

可行解决方案

方案1:使用动态import()(无需修改项目结构)

在CommonJS模块中,Node.js允许通过**动态import()**加载ESM包,这是官方推荐的兼容方式。修改你的File.ts代码:

// 替代同步导入:import * as fileType from 'file-type'
async function detectFileType(filePath: string) {
  const { fileTypeFromFile } = await import('file-type');
  const result = await fileTypeFromFile(filePath);
  // 后续逻辑
  return result;
}

如果无法使用async/await,可以用Promise回调:

import('file-type').then(({ fileTypeFromBuffer }) => {
  // 处理Buffer的逻辑
});

注意:动态import是异步操作,所有依赖file-type的逻辑需要适配异步流程。

方案2:降级file-type到v17版本

v17及更早的file-type同时支持CommonJS和ESM,无需修改代码即可直接使用。执行以下命令降级:

npm install file-type@17 --save

降级后可以继续使用原来的同步导入语法,完全兼容现有项目配置。

方案3:拆分模块(进阶,不推荐)

如果坚持使用file-type v18,可以将使用file-type的文件改为ESM模块,再在CommonJS主项目中通过动态import加载该ESM文件。但需要调整TS配置和文件命名(比如改为.mts),还需处理跨模块的类型兼容,改动成本较高,不如前两种方案高效。

为什么type: module会引发其他问题?

当你在package.json中添加"type": "module"后,整个项目会被识别为ESM模块,此时:

  • TS编译配置需要将"module"改为"ESNext"或"ES2020",否则编译后的代码会和Node.js的ESM加载规则冲突
  • 原有的require()语法必须全部改为import,涉及大量代码改动
  • 部分依赖可能仍使用CommonJS导出,需要额外处理默认导入的兼容问题
    因此这种方案会破坏现有项目的稳定性,不建议采用。

内容的提问来源于stack exchange,提问作者samala7800

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:20:29