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

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等工具的类型冲突

配套调整建议

  1. 保留package.json中的type: "module",确保Node.js以ES模块方式运行编译后的代码
  2. 继续使用tsx作为开发运行工具,无需额外配置即可支持ES模块与TypeScript热更新
  3. 若mercurius-codegen仍有调用问题,可在代码中临时用require导入该工具,或调整其配置文件指定模块类型为ES

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:13:09