Node+TypeScript+Apollo Server项目热重载启动报错求助
Node.js + GraphQL + Docker 热重载问题排查与解决方案
问题根源分析
SyntaxError: Unexpected token 'export':@apollo/server本身采用ES模块规范(使用export导出代码),但默认npm项目以CommonJS规范运行(依赖require),nodemon调用ts-node时默认以CommonJS模式解析文件,遇到ES模块语法直接报错。TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts":添加"type": "module"后,Node.js会将所有文件视为ES模块,但ts-node默认不支持直接解析ES模块类型的.ts文件,导致无法识别文件扩展名。
解决方案(修复nodemon+ts-node配置)
1. 调整TypeScript配置(tsconfig.json)
确保开启ES模块相关编译选项:
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "NodeNext", "target": "ES2020", "esModuleInterop": true, "skipLibCheck": true, "outDir": "./dist" }, "include": ["**/*.ts"], "exclude": ["node_modules"] }
2. 修正package.json配置
保留"type": "module",同时指定ts-node使用ES模块模式启动:
{ "type": "module", "scripts": { "dev": "nodemon --exec ts-node-esm index.ts", "build": "tsc", "start": "node dist/index.js" } }
注意:必须用
ts-node-esm替代ts-node,它是ts-node专门用于处理ES模块的执行入口。
3. Docker适配配置
若要在Docker中运行并实现热重载,示例Dockerfile:
FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 4000 CMD ["npm", "run", "dev"]
配套docker-compose.yml(简化本地开发):
version: '3.8' services: graphql-api: build: . ports: - "4000:4000" volumes: - ./:/app - /app/node_modules # 避免本地node_modules覆盖容器内依赖 environment: - NODE_ENV=development
替代热重载方案
如果觉得nodemon配置繁琐,可尝试以下更简洁的方案:
1. tsx
轻量型TypeScript运行时,原生支持ES模块,热重载性能更优:
- 安装:
npm install -D tsx - 替换dev脚本:
"dev": "tsx watch index.ts"
2. vite-node
基于Vite的Node.js运行时,支持极速热重载,适合中大型项目:
- 安装:
npm install -D vite vite-node - 创建
vite.config.ts:
import { defineConfig } from 'vite'; export default defineConfig({ server: { port: 4000, }, });
- 替换dev脚本:
"dev": "vite-node --watch index.ts"
3. tsc监听 + nodemon
先编译再运行,适合需要验证编译产物的场景:
- 安装:
npm install -D concurrently - 替换dev脚本:
"dev": "concurrently \"tsc --watch\" \"nodemon dist/index.js\""
内容的提问来源于stack exchange,提问作者bluedot
相关产品推荐
相关产品推荐

