Remix.run应用使用react-fusioncharts报document未定义如何解决
Remix.run 适配 react-fusioncharts 解决
document is not defined 报错 你之前加的环境守卫不生效的核心原因是:静态import的依赖会在代码执行前被引擎优先加载,而FusionCharts核心包的顶层代码就直接访问了document对象,服务端渲染阶段加载依赖时就已经抛出错误,根本不会走到你写的if (typeof document !== 'undefined')判断逻辑。
可直接落地的适配步骤如下:
- 第一步:清理所有文件顶部对
react-fusioncharts、fusioncharts、对应图表模块、主题模块的静态导入语句,不要在服务端会执行的文件里直接引入这些依赖。 - 第二步:利用Remix的
.client文件约定,把所有FusionCharts相关逻辑拆分到仅客户端运行的模块中——Remix会自动跳过后缀为.client.jsx/.client.tsx的文件的服务端打包与执行,从根源上避开SSR环境。 - 第三步:页面中渲染图表时,用客户端专属渲染组件做加载兜底,避免服务端尝试解析图表相关逻辑。
具体代码实现参考:
- 新建仅客户端运行的图表组件文件
FusionColumnChart.client.jsx:
import ReactFC from "react-fusioncharts"; import FusionCharts from "fusioncharts"; import Column2D from "fusioncharts/fusioncharts.charts"; import GammelTheme from "fusioncharts/themes/fusioncharts.theme.gammel"; // 该文件仅在浏览器环境执行,不需要额外加document判断 ReactFC.fcRoot(FusionCharts, Column2D, GammelTheme); export default function FusionColumnChart({ chartData, customConfig = {} }) { const chartConfig = { type: "column2d", width: "100%", height: 400, dataFormat: "json", dataSource: { chart: { theme: "gammel", caption: "示例柱状图", xAxisName: "维度", yAxisName: "数值" }, data: chartData }, ...customConfig }; return <ReactFC {...chartConfig} />; }
- 在业务页面/路由文件中引入使用:
import { ClientOnly } from "remix-utils/client-only"; export default function DataPage() { return ( <div className="page-wrapper"> <h3>数据统计</h3> <ClientOnly fallback={<div className="loading">图表加载中...</div>}> {() => { const FusionColumnChart = require("./FusionColumnChart.client").default; return ( <FusionColumnChart chartData={[ { label: "1月", value: "235" }, { label: "2月", value: "412" }, { label: "3月", value: "328" } ]} /> ); }} </ClientOnly> </div> ); }
注意:不要试图通过给静态import套环境判断的方式解决问题,ES模块的导入解析优先级高于任意业务代码判断,这种写法无法阻止服务端加载依赖时触发报错。使用
.client后缀拆分模块是Remix场景下最稳定的适配方案,不需要额外写环境判断守卫。
内容的提问来源于stack exchange,提问作者Michael Falck Wedelgård
相关产品推荐
相关产品推荐

