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

迁移JS项目至esbuild遇依赖导出问题:exports未定义

问题解决:从Rollup迁移到esbuild时私有npm依赖的导出错误

问题现象

  • esbuild打包时输出警告:Import "bar" will always be undefined because the file "node_modules/[path]/lib/index.js" has no exports [import-is-undefined]
  • 浏览器加载打包文件时抛出错误:Uncaught ReferenceError: exports is not defined

涉及的私有库配置与代码:

库的package.json关键字段

{
  "main": "lib",
  "type": "module",
  "types": "lib/index.d.ts",
  "files": [
    "lib/*",
    "dist/*"
  ]
}

库的导出代码(lib/index.js)

Object.defineProperty(exports, "__esModule", { value: true });
exports.Foo = void 0;
exports.Foo = {
  bar
}

function bar() {
  //...
}

浏览器报错的打包后代码片段

Object.defineProperty(exports, "__esModule", { value: true });

问题根源

这个私有库存在模块类型声明与实际代码语法不匹配的核心问题:

  • package.json中声明了"type": "module",明确告诉Node.js和构建工具(包括esbuild)该库属于ES模块;
  • 但实际代码使用的是CommonJS的exports语法,而ES模块环境(浏览器原生ES模块或esbuild打包的ES模块产物)中不存在exports全局对象,因此浏览器直接报错;
  • esbuild严格遵循ES模块规则解析该库,找不到export关键字定义的合法导出,因此提前提示导入的符号会是undefined。

解决方案

方案1:修改私有库(最优解)

调整库的配置或代码,让模块类型与语法完全一致:

  • 选项A:转为CommonJS库
    删除package.json中的"type": "module"字段,此时库会被默认识别为CommonJS模块,exports语法可正常被esbuild处理。
  • 选项B:转为ES模块语法
    保留"type": "module"字段,将代码中的CommonJS导出改为标准ES模块语法:
    export const Foo = {
      bar
    };
    
    function bar() {
      //...
    }
    
  • 选项C:双模块兼容支持
    同时提供ES模块和CommonJS版本,通过package.json的exports字段明确不同环境的入口:
    {
      "main": "lib/index.cjs",
      "module": "lib/index.mjs",
      "type": "module",
      "exports": {
        "require": "./lib/index.cjs",
        "import": "./lib/index.mjs"
      }
    }
    

方案2:在esbuild中强制处理该库(临时 workaround)

如果暂时无法修改私有库,可通过esbuild插件强制将该库识别为CommonJS模块,避免浏览器报错:

require('esbuild').build({
  entryPoints: ['src/index.js'],
  bundle: true,
  outfile: 'dist/bundle.js',
  format: 'esm', // 保持浏览器端的ES模块格式
  plugins: [
    {
      name: 'private-lib-cjs-fix',
      setup(build) {
        // 匹配你的私有库名称,替换为实际库名
        build.onResolve({ filter: /^your-private-lib-name$/ }, args => {
          return {
            path: require.resolve(args.path),
            namespace: 'cjs-lib'
          };
        });
        // 将该库的文件按CommonJS规则解析
        build.onLoad({ filter: /.*/, namespace: 'cjs-lib' }, args => {
          const fs = require('fs');
          return {
            contents: fs.readFileSync(args.path, 'utf8'),
            loader: 'cjs'
          };
        });
      }
    }
  ]
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:10:08