Yarn monorepo下Rollup打包Node.js应用运行报winston.format.combine未定义错误
问题原因
这个错误的核心是Rollup对外部CommonJS依赖的ESM兼容转换逻辑错误:
- 代码里从
winston做具名导入{ format, createLogger },而winston本身是原生CommonJS模块,没有ESM默认导出。 - Rollup的
@rollup/plugin-commonjs默认开启了外部依赖的ESM interop逻辑,给require('winston')的返回值套了一层_interopDefaultLegacy封装,强行从返回值里取.default属性作为实际导出值,导致最终拿到的winston_1是个空对象,自然找不到format属性。
解决方案
以下方案任选其一即可:
方案1:修改
rollup.config.js中@rollup/plugin-commonjs的配置,关闭外部ESM转换
给commonjs插件新增配置项esmExternals: false,修改后配置如下:commonjs({ sourceMap: !isProduction, esmExternals: false })这个参数会关闭对外部CommonJS依赖的ESM兼容封装,直接返回
require的原始结果,不再强行取.default属性,即可正常访问winston的导出属性。方案2:修改tsconfig.json的模块输出格式
将compilerOptions.module设置为ESNext,让tsc直接输出ES模块格式的代码,交给Rollup做模块处理,避免tsc先转CommonJS再被Rollup二次转换导致的导入逻辑混乱。方案3:调整导入写法兼容所有转换逻辑
将winston的导入从具名导入改为命名空间导入:import * as winston from 'winston'; // 使用时改为winston.format、winston.createLogger等这种写法不受CommonJS和ESM转换逻辑的影响,不管怎么打包都能正常访问模块导出属性。
内容的提问来源于stack exchange,提问作者bhr
相关产品推荐
相关产品推荐

