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

使用Rollup打包React组件库时依赖导出空对象问题

问题分析与解决方案

一、_virtual目录的作用

Rollup的@rollup/plugin-commonjs插件会生成_virtual目录,其中的文件是CommonJS模块转ES模块的桥接中间文件。插件处理第三方CommonJS依赖时,会创建这些虚拟模块来适配ES模块的导出规范,避免直接修改node_modules内的源码。

二、导出空对象的原因

你的配置存在两个核心问题:

  1. 插件顺序错误:commonjs插件必须放在resolve之后执行。如果先运行commonjs,此时resolve还未定位到node_modules中的依赖,插件无法正确解析第三方CommonJS模块的导出逻辑,最终生成空的exports对象。
  2. preserveModules的冲突:开启preserveModules: true后,Rollup会保留源码的模块结构,但第三方依赖的转换逻辑与模块拆分逻辑冲突,导致部分依赖(如d3-time-format、prop-types)的转换不完整,仅生成空的桥接文件。

另外,打包时出现的'default' is not exported by ...类警告,正是CommonJS模块转换失败的直接表现,与运行时的“X is not a function”错误直接相关。

三、修复步骤

1. 调整插件执行顺序

将resolve()移至commonjs()之前,确保先定位到依赖再进行CommonJS转ES模块的处理:

plugins: [
  peerDepsExternal(),
  resolve(), // 先完成依赖定位
  commonjs(), // 再处理CommonJS模块转换
  svgr({
    icon: true,
    replaceAttrValues: { '#000': '{props.color}' },
    svgProps: { fill: 'currentColor' },
  }),
  typescript(),
  babel({
    babelHelpers: 'runtime',
    exclude: /node_modules/,
    extensions: ['.js', '.ts', '.tsx'],
  }),
],

2. 明确commonjs插件的处理范围

若需要保留模块结构(preserveModules: true),需给commonjs插件配置include,确保覆盖所有node_modules中的CommonJS模块:

commonjs({
  include: /node_modules/, // 指定处理所有第三方依赖
}),

3. 优先使用ES模块版本

部分依赖(如d3-time-format)同时提供ES和CommonJS版本,可通过resolve插件强制优先使用ES模块,减少转换风险:

resolve({
  preferBuiltins: false,
  extensions: ['.js', '.ts', '.tsx', '.json'],
}),

四、验证修复

修改配置后重新打包:

  • 检查dist/_virtual下的目标文件(如d3-time-format.js),确认exports对象包含完整的导出内容,而非空对象
  • 在Next.js项目中重新安装组件库,运行后确认“X is not a function”错误消失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:55:54