NextJS集成MikroORM报错:Cannot use import statement outside a module
NextJS 集成 MikroORM 报错:SyntaxError: Cannot use import statement outside a module
问题描述
我在 NextJS v14.2.14 项目中集成 MikroORM v6.3.13,仅完成基础配置并编写了一个写入SectionEntity的基础API:
export const dynamic = "force-dynamic"; export async function GET() { const orm = await MikroORM.init(config); const em = orm.em.fork(); try { const section = new SectionEntity(); section.locale = "en"; section.page = "test"; section.type = "form"; section.key = "test_section"; await em.persistAndFlush(section); console.log(section.createdAt); return NextResponse.json("SUCCESS", { status: 200 }); } catch (error) { return NextResponse.json({ error: `${error}` }, { status: 500 }); } }
运行时触发以下错误:
import { Entity, PrimaryKey, Property, ManyToOne, type Rel } from "@mikro-orm/core"; SyntaxError: Cannot use import statement outside a module at internalCompileFunction (node:internal/vm:128:18) at wrapSafe (node:internal/modules/cjs/loader:1279:20) at Module._compile (node:internal/modules/cjs/loader:1331:27) at Module._extensions..js (node:internal/modules/cjs/loader:1426:10) at Module.load (node:internal/modules/cjs/loader:1205:32) at Module._load (node:internal/modules/cjs/loader:1021:12) at Module.require (node:internal/modules/cjs/loader:1230:19) at mod.require (C:\Projects\mikroorm-basic\node_modules\next\dist\server\require-hook.js:65:28) at require (node:internal/modules/helpers:179:18)
执行 npx mikro-orm-esm debug 验证MikroORM CLI配置正常:
Current MikroORM CLI configuration - dependencies: - mikro-orm 6.3.13 - node 21.7.1 - knex 3.1.0 - pg 8.13.0 - typescript 5.6.2 - package.json found - ts-node enabled - searched config paths: - C:/Projects/mikroorm-basic/src/mikro-orm.config.ts (not found) - C:/Projects/mikroorm-basic/mikro-orm.config.ts (found) - C:/Projects/mikroorm-basic/src/mikro-orm.config.js (not found) - C:/Projects/mikroorm-basic/mikro-orm.config.js (not found) - configuration found - database connection successful - will use `entities` array (contains 0 references and 1 paths) - C:/Projects/mikroorm-basic/server/entities (found)
实体定义
实体文件位于 ./server/entities 目录:
SectionEntity.ts
import { Entity, PrimaryKey, Property, OneToMany, Collection } from "@mikro-orm/core"; import type { SectionType } from "../types/PageContent"; import ContentEntity from "./content.entity"; @Entity() export default class SectionEntity { @PrimaryKey() id!: number; @Property() locale!: string; @Property() page!: string; @Property() type!: SectionType; @Property() key!: string; @OneToMany(() => ContentEntity, (content) => content.section) contents = new Collection<ContentEntity>(this); @Property() createdAt: Date = new Date(); }
ContentEntity.ts
import { Entity, PrimaryKey, Property, ManyToOne, type Rel } from "@mikro-orm/core"; import type { ContentType } from "../types/PageContent"; import SectionEntity from "./sections.entity"; @Entity() export default class ContentEntity { @PrimaryKey() id!: number; @ManyToOne({ entity: () => SectionEntity }) section!: Rel<SectionEntity>; @Property() type!: ContentType; @Property() key!: string; @Property() body!: string; @Property() createdAt: Date = new Date(); }
项目TS配置
尝试过多种旧版本或适配Pages Router的解决方案,均无效;添加 "type": "module" 会导致项目异常。当前 tsconfig.json 配置如下:
{ "compilerOptions": { "target": "ES2022", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "plugins": [ { "name": "next" } ], "paths": { "@/*": ["./*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] }
解决方案
针对NextJS 14 App Router + MikroORM v6的场景,按以下步骤修复:
1. 配置NextJS转译MikroORM依赖
在 next.config.js 中添加 transpilePackages,让NextJS处理MikroORM的ESM模块:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ['@mikro-orm/core', '@mikro-orm/postgresql', '@mikro-orm/knex'], } module.exports = nextConfig;
根据你使用的数据库调整包名,比如MySQL对应
@mikro-orm/mysql
2. 调整MikroORM配置文件
修改 mikro-orm.config.ts,启用ESM模式并指定元数据提供者:
import { defineConfig } from '@mikro-orm/postgresql'; import { TsMorphMetadataProvider } from '@mikro-orm/reflection'; export default defineConfig({ // 替换为你的数据库连接信息 host: 'localhost', port: 5432, user: 'your-db-user', password: 'your-db-password', dbName: 'your-db-name', entities: ['./server/entities/**/*.ts'], metadataProvider: TsMorphMetadataProvider, esm: true, tsNode: true, });
3. 修正API路由代码
确保正确导入配置和实体,并且在请求结束后关闭ORM连接:
import { MikroORM } from '@mikro-orm/postgresql'; import config from '../../mikro-orm.config'; import SectionEntity from '../../server/entities/sections.entity'; import { NextResponse } from 'next/server'; export const dynamic = "force-dynamic"; export async function GET() { let orm; try { orm = await MikroORM.init(config); const em = orm.em.fork(); const section = new SectionEntity(); section.locale = "en"; section.page = "test"; section.type = "form"; section.key = "test_section"; await em.persistAndFlush(section); console.log(section.createdAt); return NextResponse.json("SUCCESS", { status: 200 }); } catch (error) { return NextResponse.json({ error: `${error}` }, { status: 500 }); } finally { if (orm) await orm.close(); // 确保连接关闭 } }
4. 额外检查
- 确保实体文件均为
.ts扩展名,且在TS配置的include范围内 - 不要在
package.json中添加"type": "module",避免与NextJS的模块系统冲突
内容的提问来源于stack exchange,提问作者Paul S.
相关产品推荐
相关产品推荐

