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

Next.js引入第三方JavaScript失效问题排查求助

问题:Vanilla JS开发的Phaser双陆棋迁移Next.js后无反应

问题背景

原Vanilla JS版本通过HTML直接引入脚本并调用controller.createGame()即可正常运行游戏,但迁移到Next.js后,页面加载无任何反应。

原Vanilla JS核心HTML结构

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Backgammon</title>
        <link rel="stylesheet" href="build/css/min.css" type="text/css">
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
        <meta name="msapplication-tap-highlight" content="no" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black" />
        <meta name="apple-mobile-web-app-title" content="Darts Credits">
        <script src="build/js/top-min.js" type="text/javascript"></script>
    </head>
    <body>
        <div id="game"> </div>
        <script src="libs/socket.io.js"></script>

        <script src="src/controller.js" type="text/javascript"></script>
        <script src="src/global.js" type="text/javascript"></script>
        <script src="src/checker.js" type="text/javascript"></script>
        <script src="src/dice.js" type="text/javascript"></script>
        <script src="src/placeholder.js" type="text/javascript"></script>
        <script src="src/gameplay.js" type="text/javascript"></script>
        <script src="src/preload.js" type="text/javascript"></script>
        <script>controller.createGame();</script>
    </body>
</html>

Next.js当前实现

项目结构中游戏脚本放置在public/game/src目录,核心代码逻辑:

  • page.js通过动态导入关闭SSR的客户端组件
  • BackgammonComponent尝试通过Head标签引入脚本并调用游戏初始化函数

问题根源

  1. 脚本路径错误:public目录下的资源需使用绝对路径,原相对路径../game/src/xxx.js无法正确指向public下的文件,应改为/game/src/xxx.js
  2. 脚本执行时机未控制:直接在Head中添加script标签,无法保证所有依赖脚本加载完成后再执行controller.createGame(),导致初始化时controller可能未定义
  3. socket.io重复引入冲突:组件中import了socket.io-client,同时原脚本又要引入libs/socket.io.js,可能导致全局对象冲突
  4. DOM就绪问题:游戏初始化依赖#game容器存在,原代码未确保容器渲染完成后再执行初始化

修正方案

步骤1:修正资源路径

将所有脚本、样式的路径改为绝对路径,确保指向public目录下的对应文件

步骤2:用Next.js Script组件控制加载顺序

通过next/script的onLoad回调,确保最后一个依赖脚本加载完成后再初始化游戏,同时指定加载策略为afterInteractive适配游戏资源加载场景

步骤3:统一socket.io引入

移除组件中socket.io-client的import,将原项目的libs/socket.io.js放到public/game/libs目录,通过Script组件引入,避免冲突

修正后的BackgammonComponent代码

"use client";

import React, { useRef } from 'react';
import Script from 'next/script';

export default function BackgammonComponent() {
  const gameContainerRef = useRef(null);

  // 初始化游戏函数
  const initGame = () => {
    if (window.controller && gameContainerRef.current) {
      window.controller.createGame();
      console.log("游戏初始化完成");
    } else {
      console.error("controller未定义或游戏容器不存在");
    }
  };

  return (
    <main>
      <div>Game component</div>
      <div id='game' ref={gameContainerRef}></div>

      {/* 按依赖顺序加载脚本,最后一个脚本加载完成后触发初始化 */}
      <Script
        src="/game/src/top-min.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/libs/socket.io.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/src/controller.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/src/global.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/src/checker.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/src/dice.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/src/placeholder.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/src/gameplay.js"
        strategy="afterInteractive"
      />
      <Script
        src="/game/src/preload.js"
        strategy="afterInteractive"
        onLoad={initGame}
      />
      {/* 引入原项目的样式文件 */}
      <link rel="stylesheet" href="/game/build/css/min.css" type="text/css" />
    </main>
  );
}

额外排查要点

  • 打开浏览器控制台查看是否有404错误,确认资源路径是否正确
  • 检查是否有脚本报错,比如controller未定义的提示,进一步验证加载顺序
  • 确保原项目的所有依赖资源(如样式、图片等)都已同步到public目录对应位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:05:54