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)模式
- 配置package.json:明确告诉Node所有JS文件都是ESM
{ "type": "module" }
- 修改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"] }
- 启动命令:编译后直接运行ESM文件
tsc && node dist/server/index.js
方案2:使用CommonJS(CJS)模式(适合不想切换ESM的场景)
- package.json:移除
type: module字段(Node默认采用CJS) - 修改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"] }
- 启动命令:编译后运行CJS文件
tsc && node dist/server/index.js
三、实现单文件合并打包(满足你的预期需求)
TS本身不支持打包,需要借助工具将所有依赖合并为单个JS文件,推荐用esbuild(轻量快速):
- 安装依赖
npm install esbuild --save-dev
- 在package.json添加打包命令
{ "scripts": { "build": "esbuild src/server/index.ts --bundle --platform=node --outfile=dist/bundle.js" } }
- 打包并运行
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
相关产品推荐
相关产品推荐

