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

TypeScript编译运行报错:Cannot use import statement outside a module

解决TypeScript编译后出现“SyntaxError: Cannot use import statement outside a module”的问题

问题核心

你遇到的错误本质是:编译后的JS文件被Node当作CommonJS(CJS)模块加载,但文件内使用了ES模块(ESM)的import语法,加上导入路径、TS配置与打包目标未对齐,导致常规配置调整无效。


一、先修正最基础的导入路径错误

你的index.ts直接导入了编译后的server.js,这会导致TS编译逻辑混乱,应改为导入TS源文件:

// src/server/index.ts
// 替换原导入语句,TS会自动识别.ts后缀
import './core/server';

二、统一模块系统配置(二选一)

方案1:使用ES模块(ESM)模式

  1. 配置package.json:明确告诉Node所有JS文件都是ESM
{
  "type": "module"
}
  1. 修改tsconfig.json:让TS编译输出符合ESM规范
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist", // 指定编译输出目录
    "rootDir": "./src", // 指定TS源文件根目录
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
  1. 启动命令:编译后直接运行ESM文件
tsc && node dist/server/index.js

方案2:使用CommonJS(CJS)模式(适合不想切换ESM的场景)

  1. package.json:移除type: module字段(Node默认采用CJS)
  2. 修改tsconfig.json:让TS输出CJS格式代码
{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "moduleResolution": "Node",
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
  1. 启动命令:编译后运行CJS文件
tsc && node dist/server/index.js

三、实现单文件合并打包(满足你的预期需求)

TS本身不支持打包,需要借助工具将所有依赖合并为单个JS文件,推荐用esbuild(轻量快速):

  1. 安装依赖
npm install esbuild --save-dev
  1. 在package.json添加打包命令
{
  "scripts": {
    "build": "esbuild src/server/index.ts --bundle --platform=node --outfile=dist/bundle.js"
  }
}
  1. 打包并运行
npm run build && node dist/bundle.js

四、额外优化建议

  • Prisma异步操作处理:prisma.accounts.count()是异步函数,直接输出会得到Promise对象,建议封装为异步初始化逻辑:
// src/server/core/server.ts
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function init() {
  console.log(`Script has been started`);
  await prisma.$connect();
  const accountCount = await prisma.accounts.count();
  console.log(`Prisma connected, counting accounts - ${accountCount}`);
}

// 捕获初始化错误并优雅退出
init().catch(async (err) => {
  console.error('初始化失败:', err);
  await prisma.$disconnect();
  process.exit(1);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:05:27