从CRA迁移至Vite后,使用@rollup/plugin-commonjs仍遇模块导出错误
解决Vite迁移中第三方ESM依赖导入CommonJS模块的导出错误
问题场景
将React项目从CRA(Webpack)迁移到Vite(Rollup)时,已配置@rollup/plugin-commonjs解决了自身代码导入CommonJS模块的「name-is-not-exported-by-module」错误,但第三方ESM模块(如react-router@7.6.2)导入第三方CommonJS模块(如cookie@1.0.2)时,仍触发该错误:
✗ Build failed in 11.17s ../common/temp/node_modules/.pnpm/react-router@7.6.2_react-dom@19.1.0+react@19.1.0/node_modules/react-router/dist/development/chunk-NL6KNZEE.mjs (9973:9): "parse" is not exported by "../common/temp/node_modules/.pnpm/cookie@1.0.2/node_modules/cookie/dist/index.js", imported by "../common/temp/node_modules/.pnpm/react-router@7.6.2_react-dom@19.1.0+react@19.1.0/node_modules/react-router/dist/development/chunk-NL6KNZEE.mjs".
项目处于monorepo环境,原Vite配置已设置commonjs({include: /node_modules/,})。
解决方案
1. 调整插件顺序并补充CommonJS导出映射
Rollup插件执行顺序会影响转换结果,需将resolve放在commonjs之前;同时针对cookie这类无明确ES导出的旧版CommonJS模块,手动指定命名导出:
import {reactRouter} from "@react-router/dev/vite"; import tailwindcss from "@tailwindcss/vite"; import {defineConfig, searchForWorkspaceRoot} from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; import commonjs from "@rollup/plugin-commonjs"; import resolve from "@rollup/plugin-node-resolve"; export default defineConfig({ server: { fs: { allow: [searchForWorkspaceRoot(process.cwd()), ".."], }, }, plugins: [ resolve(), // 先解析模块路径 commonjs({ include: /node_modules/, // 手动指定cookie模块的命名导出 namedExports: { "cookie": ["parse"] } }), tailwindcss(), reactRouter(), tsconfigPaths(), ], });
2. 启用Vite预构建优化
Vite的optimizeDeps会将CommonJS依赖预构建为ESM格式,从根源避免导出不匹配问题,添加以下配置:
export default defineConfig({ // ...其他配置 optimizeDeps: { include: ["cookie"], esbuildOptions: { // 强制将cookie转为ESM format: "esm" } }, // ...插件配置 });
3. 升级依赖版本(可选)
cookie@1.0.2版本较旧,检查并升级到支持ESM的版本后,无需额外配置即可兼容Vite的模块解析规则。
原理说明
第三方ESM模块直接导入旧版CommonJS模块时,Rollup的commonjs插件可能无法自动识别模块的导出结构,尤其是嵌套依赖(依赖的依赖)场景。调整插件顺序确保模块先被解析,手动指定导出或通过Vite预构建将CJS转为ESM,都能让Rollup正确识别导出内容。
内容的提问来源于stack exchange,提问作者Jthorpe
相关产品推荐
相关产品推荐

