TypeScript tsconfig target/module冲突:Fastify+Mercurius服务改造问题
问题背景与冲突点
- 技术栈:基于Fastify + Mercurius开发的Node.js GraphQL服务,原JavaScript实现转TypeScript
- 核心约束:需支持ES2017及以上版本,代码中使用顶层await(主代码1处,导入的
neo4j.mjs中2处) - 编译选项冲突场景:
module: CommonJS:触发await is only valid in async functions and the top level bodies of modules错误module: Node16/NodeNext:出现Mercurius插件类型不兼容、mercurius-codegen无法调用的错误module: ESNext/ES2022+moduleResolution: NodeNext:仍存在类型不兼容问题
相关代码与配置片段
index.ts 核心代码
import Fastify from 'fastify'; import mercurius from 'mercurius'; import { initNeo4j } from './neo4j.mjs'; // 顶层await const neo4jDriver = await initNeo4j(); const app = Fastify({ logger: true }); const schema = ` type Query { hello: String! } `; const resolvers = { Query: { hello: () => 'Hello World!' } }; app.register(mercurius, { schema, resolvers }); app.listen({ port: 3000 }, (err) => { if (err) { app.log.error(err); process.exit(1); } });
典型错误信息
module: CommonJS时:SyntaxError: await is only valid in async functions and the top level bodies of modules
module: Node16时:Type 'typeof import("mercurius")' is not assignable to type 'FastifyPluginAsync<mercurius.MercuriusOptions, RawServerDefault>'. Error: mercurius-codegen: Failed to generate types, please check your schema and resolvers.
package.json 关键配置
{ "name": "graphql-service", "version": "1.0.0", "type": "module", "scripts": { "dev": "tsx watch src/index.ts", "build": "tsc", "start": "node dist/index.js" }, "dependencies": { "fastify": "^4.24.3", "mercurius": "^13.0.0", "neo4j-driver": "^5.15.0" }, "devDependencies": { "@types/node": "^20.9.0", "mercurius-codegen": "^5.0.0", "tsx": "^4.1.0", "typescript": "^5.2.2" } }
适配的tsconfig.json配置方案
{ "compilerOptions": { "target": "ES2017", "module": "ESNext", "moduleResolution": "Node", "allowTopLevelAwait": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "skipLibCheck": true, "strict": true, "outDir": "./dist", "rootDir": "./src", "resolveJsonModule": true, "types": ["node"] }, "include": ["src/**/*"], "exclude": ["node_modules"] }
配置说明
target: ES2017:满足ES2017+兼容性要求module: ESNext+allowTopLevelAwait: true:原生支持顶层await,避开CommonJS的限制moduleResolution: Node:使用传统Node模块解析逻辑,解决Mercurius类型不兼容问题esModuleInterop+allowSyntheticDefaultImports:适配CommonJS模块的导入语法,消除类型报错skipLibCheck: true:跳过第三方库的类型检查,绕过mercurius-codegen等工具的类型冲突
配套调整建议
- 保留
package.json中的type: "module",确保Node.js以ES模块方式运行编译后的代码 - 继续使用
tsx作为开发运行工具,无需额外配置即可支持ES模块与TypeScript热更新 - 若
mercurius-codegen仍有调用问题,可在代码中临时用require导入该工具,或调整其配置文件指定模块类型为ES
内容的提问来源于stack exchange,提问作者ankou29666
相关产品推荐
相关产品推荐

