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导入这个组件:
- 封装图表组件
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> }
- 在父组件中动态导入,关闭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
相关产品推荐
相关产品推荐

