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

如何在Next.js项目中编译public目录下的TypeScript文件

问题:Next.js项目中public目录下TypeScript文件编译后浏览器报错exports is not defined

场景与报错

现有正常运行的Next.js TypeScript项目,计划在public目录下开发小型游戏,目录结构如下:

  • rootfolder/pages/game.tsx
  • rootfolder/public/game/app.ts

执行tsc public/game/app.ts完成编译后,浏览器加载页面时出现报错:

Unhandled Runtime Error
ReferenceError: exports is not defined

现有代码如下:

game.tsx

import Head from 'next/head';
import Script from 'next/script';

export default function Game() {
  return (
    <>
      <Head>
        <title>My Game</title>
      </Head>
      <Script type='module' src='game/app.js' />

      <div className='h-[100vh] bg-gray-600 flex justify-center items-center'>
        <div className='game-container scale-125'>
          <canvas
            className='game-canvas border-2 border-gray-300'
            width='700px'
            height='400px'
          />
        </div>
      </div>
    </>
  );
}

app.ts

console.log('hi');

export default {};

编译后的app.js

"use strict";
exports.__esModule = true;
console.log('hi');
exports["default"] = {};

全局tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": false,
    "esModuleInterop": true,
    "noUnusedLocals": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./*"]
    }
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "public/game/app.js",
    "public/game/app.ts"
  ],
  "exclude": ["node_modules"]
}

原因分析

报错核心在于:浏览器通过type='module'加载脚本时仅支持ES模块语法,但直接用全局tsconfig编译public/game/app.ts时,生成的JS代码采用了CommonJS的exports语法,导致浏览器无法识别。

全局tsconfig中配置的module: "esnext"因Next.js自身构建逻辑,单独执行tsc命令时并未生效,最终编译产物仍为CommonJS格式。

解决方案

1. 为游戏代码创建独立TypeScript配置

在项目根目录新建tsconfig.game.json,专门针对public下的游戏TS文件配置ES模块编译规则:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "ESNext",
    "lib": ["dom", "esnext"],
    "strict": true,
    "esModuleInterop": true,
    "outDir": "./public/game",
    "rootDir": "./public/game"
  },
  "include": ["public/game/**/*.ts"],
  "exclude": ["node_modules"]
}

2. 修改编译命令

使用新配置文件编译游戏代码,替换原有的tsc public/game/app.ts:

tsc --project tsconfig.game.json

编译后生成的app.js会采用ES模块语法,不再出现exports:

console.log('hi');
export default {};

3. (可选)简化编译流程

在package.json的scripts中添加游戏编译命令,方便后续使用:

{
  "scripts": {
    "build:game": "tsc --project tsconfig.game.json"
  }
}

之后执行npm run build:game即可快速完成游戏代码编译。

4. 验证

重新编译后,浏览器加载页面时不再报错,控制台可正常输出hi。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:44:57