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

为何Node.js中部分无默认导出的ESM包可被默认导入?

问题:为什么无默认导出的ESM包有的能默认导入,有的不行?

场景复现

自己编写一个ESM模块:

// greetings.js
export const hello = 'hello';
export const hi = 'hi';

尝试用默认导入方式引入:

import greetings from './greetings.js';

会触发预期错误:

The requested module './greetings.js' does not provide an export named 'default'

奇怪的差异

但实际使用第三方包时,却出现了例外:比如yup可以直接默认导入:

import yup from 'yup';

查看yup的ESM入口文件index.esm.js,发现它没有显式的默认导出,但导入却能正常运行;而同样提供CommonJS模块的rotating-file-stream,尝试默认导入时却会触发上述错误。

测试验证

测试1:yup(版本1.4.0)

import yup from 'yup';

console.log(yup);

→ 正常运行,输出包含yup所有API的对象。

测试2:rotating-file-stream(版本3.2.3)

import rfs from 'rotating-file-stream';

console.log(rfs);

→ 报错,提示模块没有默认导出。


原因解析

1. 包的ESM入口是否做了默认导出兼容

仔细核对yup 1.4.0的index.esm.js会发现,它其实隐含了默认导出逻辑,代码结构大致如下:

// 内部定义完整的yup API对象
const yup = { string: /* ... */, number: /* ... */ };

// 同时导出默认和命名
export default yup;
export { yup };

可能你查看时遗漏了默认导出的声明,导致误以为没有默认导出。

而rotating-file-stream的ESM入口仅使用了命名导出,没有设置默认导出:

export function createStream(options) { /* ... */ }
// 无 export default 声明

因此用默认导入时,自然会触发“找不到默认导出”的错误。

2. CommonJS模块的ESM导入逻辑差异

如果包的ESM入口确实没有默认导出,但你仍能默认导入,那大概率是因为Node.js在处理CommonJS模块转ESM导入时的特殊逻辑:

  • 若CommonJS模块是通过module.exports = 完整对象导出的(比如yup的CommonJS入口),Node.js会自动将其映射为ESM的默认导出,所以import yup from 'yup'能正常工作。
  • 若CommonJS模块是通过exports.xxx = 函数/变量的命名导出方式(比如rotating-file-stream的CommonJS入口),Node.js不会自动生成默认导出,必须使用import { createStream } from 'rotating-file-stream'这种命名导入方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:25:19