fix: 修复 Vercel serverless 运行时崩溃

关键修复:
- 使用 require() 而非 import() 动态加载编译后的模块
- 从 dist/src/ 路径加载模块(Vercel 构建后的路径)
- 移除 tsconfig 中对 api 目录的排除
- 配置 vercel.json 路由到 dist/api/index.js

技术说明:
- api/index.ts 会被编译到 dist/api/index.js
- 运行时从 dist/src/app.module 加载 NestJS 应用
- 使用 require 避免 TypeScript 编译时路径检查

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
golc 2026-03-04 11:14:09 +00:00
parent 6cb67ead1e
commit f557f8581b
3 changed files with 19 additions and 7 deletions

View File

@ -5,9 +5,6 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import express from 'express';
import bodyParser from 'body-parser';
// 从源码导入TypeScript 会编译到 dist
import { AppModule } from '../src/app.module';
// 缓存 app 实例,避免每次冷启动都重新创建
let cachedApp: any;
@ -15,6 +12,9 @@ async function bootstrap() {
if (!cachedApp) {
const expressApp = express();
// 使用 require 动态加载编译后的模块(避免 TypeScript 编译时检查)
const { AppModule } = require('../dist/src/app.module');
const app = await NestFactory.create(
AppModule,
new ExpressAdapter(expressApp),
@ -38,8 +38,8 @@ async function bootstrap() {
// 尝试加载全局过滤器和拦截器
try {
const { HttpExceptionFilter } = await import('../src/common/filters/http-exception.filter');
const { TransformInterceptor } = await import('../src/common/interceptors/transform.interceptor');
const { HttpExceptionFilter } = require('../dist/src/common/filters/http-exception.filter');
const { TransformInterceptor } = require('../dist/src/common/interceptors/transform.interceptor');
app.useGlobalFilters(new HttpExceptionFilter());
app.useGlobalInterceptors(new TransformInterceptor());
} catch (error) {

View File

@ -18,5 +18,5 @@
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
},
"exclude": ["node_modules", "dist", "api"]
"exclude": ["node_modules", "dist"]
}

View File

@ -1,3 +1,15 @@
{
"version": 2
"version": 2,
"builds": [
{
"src": "package.json",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/dist/api/index.js"
}
]
}