【nextjs】【antd charts】nextjs13 + antd charts 渲染图表报ERR_REQUIRE_ESM错误

复现:
先 create-next-app,然后新建一个charts.jsx页面,放入antd的折线图示例代码。run dev 然后访问图表页面

import React, { useState, useEffect } from 'react';
import { Line } from '@ant-design/plots';

const DemoLine = () => {
  const data = [
    {
      year: '1991',
      value: 3,
    },
    {
      year: '1992',
      value: 4,
    },
    {
      year: '1993',
      value: 3.5,
    },
    {
      year: '1994',
      value: 5,
    },
    {
      year: '1995',
      value: 4.9,
    },
    {
      year: '1996',
      value: 6,
    },
    {
      year: '1997',
      value: 7,
    },
    {
      year: '1998',
      value: 9,
    },
    {
      year: '1999',
      value: 13,
    },
  ];
  const config = {
    data,
    xField: 'year',
    yField: 'value',
    label: {},
    point: {
      size: 5,
      shape: 'diamond',
      style: {
        fill: 'white',
        stroke: '#5B8FF9',
        lineWidth: 2,
      },
    },
    tooltip: {
      showMarkers: false,
    },
    state: {
      active: {
        style: {
          shadowBlur: 4,
          stroke: '#000',
          fill: 'red',
        },
      },
    },
    interactions: [
      {
        type: 'marker-active',
      },
    ],
  };
  return <Line {...config} />;
};

export default DemoLine

然后就会报:

- error Error [ERR_REQUIRE_ESM]: require() of ES Module D:\projects\learnnext\node_modules\d3-interpolate\src\index.js from D:\projects\learnnext\node_modules\@antv\g-base\lib\animate\timeline.js not supported.
Instead change the require of index.js in D:\projects\learnnext\node_modules\@antv\g-base\lib\animate\timeline.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g-base\lib\animate\timeline.js:5:24)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g-base\lib\abstract\canvas.js:7:18)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g-base\lib\index.js:17:16)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g2\lib\dependents.js:6:16)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g2\lib\util\scale.js:7:20)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g2\lib\util\axis.js:6:15)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g2\lib\facet\facet.js:7:14)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g2\lib\facet\index.js:5:15)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g2\lib\chart\view.js:8:15)
    at Object.<anonymous> (D:\projects\learnnext\node_modules\@antv\g2\lib\chart\chart.js:8:38)
er.js:1300:24)
    at async DevServer.renderToResponseImpl (D:\projects\learnnext\node_modules\next\dist\server\base-server.js:1343:32)
    at async DevServer.pipeImpl (D:\projects\learnnext\node_modules\next\dist\server\base-server.js:627:25)
    at async Object.fn (D:\projects\learnnext\node_modules\next\dist\server\next-server.js:1136:21)
    at async Router.execute (D:\projects\learnnext\node_modules\next\dist\server\router.js:315:32)
    at async DevServer.runImpl (D:\projects\learnnext\node_modules\next\dist\server\base-server.js:601:29)
    at async DevServer.run (D:\projects\learnnext\node_modules\next\dist\server\dev\next-dev-server.js:922:20)
    at async DevServer.handleRequestImpl (D:\projects\learnnext\node_modules\next\dist\server\base-server.js:533:20) {
  digest: undefined
}

初学nextjs,目前搜了(csdn StackOverflow 问了chatgpt)大多数解决方案未果,还请指点。

感谢哇

引用chatgpt部分指引作答:
这个错误是由于 @antv/g-base 中的一个依赖 d3-interpolate 使用了 ES 模块,在 CommonJS 模块中使用 require 引入时会报错。

解决方法是将 d3-interpolate 的引用改为动态 import 的方式。可以在 @antv/g-base 库的 lib/animate/timeline.js 中,将 require('d3-interpolate') 改为 import('d3-interpolate')。

修改后的代码如下所示:

// 将
const interpolate = require('d3-interpolate');
// 改为
const interpolate = await import('d3-interpolate');

1 在 Next.js 中,可以使用 next-transpile-modules 模块来处理这个问题。具体的操作步骤如下:

安装 next-transpile-modules 模块:

npm install --save-dev next-transpile-modules

2 在 next.config.js 中配置需要 transpile 的模块:

const withTM = require('next-transpile-modules')(['@antv/g-base']);
module.exports = withTM({
  // your other next.js configs...
});

3 在页面中引入 antd 的折线图组件并渲染。

import dynamic from 'next/dynamic';
const DemoLine = dynamic(
  () => import('../components/charts'),
  { ssr: false }
);

export default function Home() {
  return (
    <div>
      <DemoLine />
    </div>
  )
}

最后,需要注意的是,如果使用了动态 import,需要在 dynamic 的第二个参数中设置 ssr: false,表示在客户端渲染页面时才会加载动态组件。因为服务端没有浏览器环境,不支持动态 import,所以需要在客户端渲染时加载动态组件。