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

TypeScript类循环引用报错:exports is not defined 求助

解决TypeScript循环实例化类时的exports未定义错误

问题根源

你的代码存在两个核心问题:

  1. 循环导入+提前实例化:GamePanel和Player互相导入,且GamePanel在类属性定义阶段就直接实例化Player,此时GamePanel的实例还未完成构造,模块加载时会出现循环引用死锁。
  2. 模块编译目标不兼容浏览器:TypeScript默认编译为CommonJS模块,浏览器原生不支持exports/require语法,因此抛出exports is not defined错误。

修复步骤

1. 解决循环依赖与实例化时机问题

  • 不要在类属性初始化阶段直接创建Player实例,移到GamePanel的构造函数中执行,确保实例已完成基础属性初始化。
  • 对Player中的GamePanel引用使用类型导入(import type),因为这里仅用它做类型校验,不需要运行时的模块引用,避免循环加载。

修改后的代码:

GamePanel.ts

import { Player } from "./Player";

export class GamePanel {
    canvas: HTMLCanvasElement;
    c: CanvasRenderingContext2D;
    count: number = 0;
    public player: Player; // 仅声明,不提前初始化

    constructor() {
        this.canvas = <HTMLCanvasElement>document.querySelector("canvas");
        const c = this.canvas.getContext("2d");
        
        if (!c) {
            throw new Error("获取Canvas上下文失败");
        }

        this.c = c;
        this.player = new Player(this); // 构造函数内初始化Player,此时实例已就绪
    }
}

Player.ts

// 类型导入,编译后会被移除,不会产生运行时循环依赖
import type { GamePanel } from "./GamePanel";

export class Player {
    gp: GamePanel;

    constructor(gp: GamePanel) {
        this.gp = gp;
    }   

    public draw(c: CanvasRenderingContext2D): void {
        c.fillStyle = "red";
        c.fillRect(200, 200, 200, 200);
        console.log("appeared");
        const image = new Image();
        image.src = "../img/down.png";
        // 图片加载是异步的,必须等待加载完成再绘制
        image.onload = () => {
            c.drawImage(image, 300, 300, 100, 100);
            c.drawImage(image, 300, 400, 100, 100);
        };
    }
}

2. 修复浏览器模块兼容性问题

修改tsconfig.json,将编译目标设置为浏览器支持的ES模块:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "outDir": "./dist" // 编译后的文件输出目录
  },
  "include": ["**/*.ts"] // 包含所有TS文件
}

然后在HTML中引入编译后的JS文件时,必须加上type="module":

<script type="module" src="./dist/GamePanel.js"></script>

额外说明

  • 图片加载的异步问题:原代码直接调用drawImage时图片尚未加载完成,会导致绘制失败,因此需要通过onload事件确保图片加载完成后再执行绘制逻辑。
  • 如果项目规模较大,建议使用Vite、Webpack等打包工具,它们能更好地处理模块依赖和浏览器兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:02:24