import { NestFactory } from '@nestjs/core'; import { ExpressAdapter } from '@nestjs/platform-express'; import { ValidationPipe } from '@nestjs/common'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import express from 'express'; import bodyParser from 'body-parser'; import * as path from 'path'; // 缓存 app 实例,避免每次冷启动都重新创建 let cachedApp: any; async function bootstrap() { if (!cachedApp) { const expressApp = express(); // 动态解析 dist 目录路径 // 在 Vercel 环境中,__dirname 是 /var/task/api // dist 目录在 /var/task/dist const distPath = path.resolve(__dirname, '..', 'dist', 'app.module'); console.log('Loading AppModule from:', distPath); const { AppModule } = require(distPath); const app = await NestFactory.create( AppModule, new ExpressAdapter(expressApp), { logger: ['error', 'warn', 'log'] }, ); // 配置 CORS app.enableCors({ origin: true, // 允许所有来源 credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], allowedHeaders: [ 'Content-Type', 'Authorization', 'Accept', 'Origin', 'Referer', 'User-Agent', ], }); // 尝试加载全局过滤器和拦截器 try { const httpExceptionFilterPath = path.resolve( __dirname, '..', 'dist', 'common', 'filters', 'http-exception.filter', ); const transformInterceptorPath = path.resolve( __dirname, '..', 'dist', 'common', 'interceptors', 'transform.interceptor', ); const { HttpExceptionFilter } = require(httpExceptionFilterPath); const { TransformInterceptor } = require(transformInterceptorPath); app.useGlobalFilters(new HttpExceptionFilter()); app.useGlobalInterceptors(new TransformInterceptor()); } catch (error) { console.log('Global filters/interceptors not loaded:', error.message); } // 全局验证管道 app.useGlobalPipes( new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, }), ); // Body parser 配置 app.use(bodyParser.json({ limit: '50mb' })); app.use(bodyParser.urlencoded({ limit: '50mb', extended: true })); // Swagger 文档 const config = new DocumentBuilder() .setTitle('API 文档') .setDescription('这是我的应用程序的 API 文档') .setVersion('1.0') .addBearerAuth() .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('docs', app, document); await app.init(); cachedApp = expressApp; console.log('NestJS app initialized successfully'); } return cachedApp; } // Vercel Serverless handler export default async function handler(req: any, res: any) { try { console.log(`Request: ${req.method} ${req.url}`); const app = await bootstrap(); app(req, res); } catch (error) { console.error('Handler error:', error); res.status(500).json({ error: 'Internal Server Error', message: error.message, stack: process.env.NODE_ENV === 'development' ? error.stack : undefined, }); } }