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

无法在ESM项目中使用CommonJS npm包的问题排查

问题原因与解决方案

Vite 对常规npm安装的第三方包和npm link的本地包采用不同的处理逻辑:

  • 从私有仓库安装的包会被Vite自动纳入预构建流程,Vite会把CommonJS格式的代码转译为ESM兼容的格式,所以不会报错。
  • 而npm link的包是直接引用本地文件路径,Vite会把它当成项目源码的一部分,不会自动做CommonJS转ESM的处理。当你的React项目(ESM环境)直接导入CommonJS代码时,代码里的module变量在ESM环境中不存在,就会抛出ReferenceError: module is not defined。

另外你的package.json exports配置里,import字段直接指向了CommonJS的index.js,这在Vite处理link包时会加剧问题——Vite会按ESM规则解析这个文件,自然识别不了CommonJS的module对象。

解决办法

1. 让Vite预构建link的包(最直接)

在项目的vite.config.js中,把你的包名加入optimizeDeps.include列表,强制Vite对它做预构建处理:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  optimizeDeps: {
    include: ['service-provider'] // 加入你的包名
  }
});

修改后重启Vite服务,预构建会把CommonJS代码转成ESM兼容格式,报错就会消失。

2. 临时调整包的导出逻辑(可选)

如果不想改Vite配置,可以在你的包的index.js里加一层兼容判断,同时支持CommonJS和ESM:

'use strict';
const service = require('./source');

if (typeof module !== 'undefined') {
  module.exports = service;
}
if (typeof exports !== 'undefined') {
  Object.assign(exports, service);
}
if (typeof define === 'function' && define.amd) {
  define(() => service);
}
if (typeof window !== 'undefined') {
  window.RoutingService = service.RoutingService;
}

不过这个方法只是临时兼容,不如第一种方法彻底。

3. 检查package.json的exports配置(优化建议)

虽然你不想用双模块策略,但可以调整exports配置,明确告诉Node/Vite该如何处理不同导入方式:

"exports": {
  ".": {
    "require": "./index.js",
    "import": "./index.js",
    "default": "./index.js"
  }
},

同时确保type: "commonjs"保留,这样常规安装的包依然能正常工作,link的包配合Vite预构建也没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:43:25