Next.js(TypeScript)集成Recharts时ES模块导入错误求助
在Next.js 12(原生支持ES模块)+ TypeScript项目中集成Recharts时,编译阶段出现如下错误:
Error: Must use import to load ES Module: project_path\node_modules\d3-shape\src\index.js
require() of ES modules is not supported.
require() of project_path\node_modules\d3-shape\src\index.js from project_path\node_modules\recharts\lib\shape\Symbols.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from project_path\node_modules\d3-shape\package.json.
问题根源:d3-shape已采用ES模块规范,但Recharts编译后的代码仍使用require()导入它,而非import,导致Next.js的模块解析逻辑冲突。
可行解决方案
1. 配置Next.js转译相关依赖
在next.config.js中添加transpilePackages配置,让Next.js转译Recharts和d3-shape,统一模块处理方式:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ['recharts', 'd3-shape'], // 其他已有的配置... } module.exports = nextConfig
2. 降级d3-shape到兼容版本
查找Recharts当前版本适配的非ES模块版本的d3-shape,在package.json中指定具体版本后重新安装:
比如若使用Recharts v2.x,可尝试安装d3-shape@2.1.0:
npm install d3-shape@2.1.0 --save-exact
使用yarn则执行:
yarn add d3-shape@2.1.0 --exact
3. 动态导入Recharts组件
使用Next.js的dynamic导入API,禁用服务端渲染(SSR)加载Recharts组件,绕开服务端的模块解析冲突:
import dynamic from 'next/dynamic'; // 禁用SSR加载Recharts组件 const LineChart = dynamic(() => import('recharts').then((mod) => mod.LineChart), { ssr: false, }); const MyChart = () => { return ( <LineChart width={600} height={300} data={[]}> {/* 图表内容 */} </LineChart> ); }; export default MyChart;
4. 自定义Webpack配置处理ES模块
修改next.config.js的webpack配置,将d3-shape视为ES模块处理:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config, { isServer }) => { // 处理d3-shape的ES模块 config.module.rules.push({ test: /\.js$/, include: /node_modules\/d3-shape/, type: 'javascript/auto', }); return config; }, }; module.exports = nextConfig;
内容的提问来源于stack exchange,提问作者Michael Rabinovich

