NextJS 14.1.3脚本加载不稳定,求助排查解决方法
NextJS 14.1.3脚本偶发加载失败问题的修复方案
问题核心
你的问题本质是脚本加载顺序不明确和组件初始化时机与脚本加载完成时机的竞态,加上原代码中存在DOM元素缺失的问题,共同导致了偶发的加载失败。
关键修复步骤
1. 修复Chart组件的DOM缺失问题
原Chart.tsx中return ()是空的,导致buildChart找不到目标元素,这是必现的问题之一:
// Chart.tsx export default function NetWorthChart() { useEffect(() => { // ... 后续逻辑 }, []); // 必须渲染出图表容器DOM return <div id="hs-sales-line-chart"></div>; }
2. 控制脚本加载顺序,确保依赖就绪
由于hs-apexcharts-helpers.js依赖lodash和apexcharts,必须保证前两个脚本加载完成后再加载自定义helper。可以手动创建脚本并通过onload链式加载,避免Next.js Script组件并行加载的顺序问题:
// Layout.tsx export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en"> <body> {/* 手动链式加载脚本,保证依赖顺序 */} <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js" onload={() => { const apexScript = document.createElement('script'); apexScript.src = 'https://cdn.jsdelivr.net/npm/apexcharts'; apexScript.onload = () => { const helperScript = document.createElement('script'); helperScript.src = '/hs-apexcharts-helpers.js'; document.body.appendChild(helperScript); }; document.body.appendChild(apexScript); }} /> {children} </body> </html> ); }
3. 显式暴露全局函数
确保自定义helper中的buildChart挂载到全局window对象,避免严格模式下无法访问:
// public/hs-apexcharts-helpers.js // 显式挂载到window window.buildChart = function(selector) { // 原函数逻辑 };
4. 添加依赖检查与重试机制
在组件中不要直接调用buildChart,而是检查所有依赖是否就绪,未就绪则延迟重试:
// Chart.tsx export default function NetWorthChart() { useEffect(() => { let retryTimer: NodeJS.Timeout; function initChart() { // 检查所有依赖:window存在、apexcharts已加载、buildChart函数存在 if (typeof window !== 'undefined' && window.apexcharts && typeof window.buildChart === 'function') { window.buildChart('#hs-sales-line-chart'); } else { // 100ms后重试,可自行调整重试间隔与次数 retryTimer = setTimeout(initChart, 100); } } initChart(); // 组件卸载时清理定时器 return () => clearTimeout(retryTimer); }, []); return <div id="hs-sales-line-chart"></div>; }
备选方案:使用npm包替代CDN加载
如果允许,直接通过npm安装apexcharts和lodash,避免CDN加载不稳定的问题:
npm install apexcharts lodash
然后在组件中直接导入使用,完全不需要Script组件:
// Chart.tsx import apexcharts from 'apexcharts'; import _ from 'lodash'; import { buildChart } from '../utils/hs-apexcharts-helpers'; // 把helper移到src目录作为模块 export default function NetWorthChart() { useEffect(() => { buildChart('#hs-sales-line-chart'); }, []); return <div id="hs-sales-line-chart"></div>; }
内容的提问来源于stack exchange,提问作者Jiroscopes
相关产品推荐
相关产品推荐

