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

Next.js 非SSR场景下具名导入转动态导入的问题排查

问题原因

你的导入写法错误,和charting_library的JS文件本身无关:next/dynamic 是Next.js专门用于动态导入React组件的API,不能用来导入普通JS模块导出的类、函数等非组件内容,你原来的写法会把widget类当作React组件处理,运行时尝试渲染自然会报错。

修正方案

根据你的使用场景,二选一即可:

方案1:直接在客户端用useEffect动态导入(推荐)

如果是Next.js 13+ App Router,先给组件加上'use client'标识,再通过useEffect在客户端侧动态加载模块:

'use client'
import { useState, useEffect } from 'react'

export default function ChartPage() {
  const [widget, setWidget] = useState(null)

  useEffect(() => {
    // 仅在客户端执行导入,相当于关闭SSR
    const loadChartModule = async () => {
      const chartModule = await import("./charting_library/charting_library")
      setWidget(chartModule.widget)
    }
    loadChartModule()
  }, [])

  useEffect(() => {
    // 确认模块加载完成后再实例化
    if (!widget) return
    // 这里写你原来的widget实例化逻辑
    new widget({
      // 你的图表配置
      container_id: "chart-container"
    })
  }, [widget])

  return <div id="chart-container" style={{ width: '100%', height: '600px' }}></div>
}

如果是Pages Router,去掉顶部的'use client'即可,其余逻辑一致。

方案2:封装为组件后用dynamic导入

如果你希望保持dynamic的写法,可以先把图表相关逻辑封装为独立React组件,再用dynamic导入这个组件:

  1. 封装图表组件components/ChartWidget.js:
import { widget } from "../charting_library/charting_library";
import { useEffect } from 'react'

export default function ChartWidget(props) {
  useEffect(() => {
    new widget({
      container_id: "chart-container",
      // 其余配置项
      ...props
    })
  }, [props])

  return <div id="chart-container" style={{ width: '100%', height: '600px' }}></div>
}
  1. 在父组件中动态导入,关闭SSR:
import dynamic from 'next/dynamic'

// 动态导入React组件时才可以用dynamic+ssr:false配置
const ChartWidget = dynamic(() => import("@/components/ChartWidget"), {
  ssr: false
})

export default function Page() {
  // 直接当作普通组件调用即可
  return <ChartWidget />
}

内容的提问来源于stack exchange,提问作者margherita pizza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:36:05