使用Serverless时NestJS注入服务为undefined问题求助
NestJS + Serverless Offline 依赖注入失效问题
问题现象
使用ts-node-dev启动应用时,所有服务的依赖注入正常工作;但运行npx serverless offline时,SegurosEstadoController构造函数中的UtilsService、SegurosEstadoService、LoggerService均为undefined,调用服务方法会抛出Cannot read properties of undefined (reading 'getHello')错误。
核心问题定位
- 模块配置错误:在
seguros-estado.module.ts中,将服务类ErrorsService错误地放在了imports数组中(imports仅支持导入模块类)。 - TypeScript编译缺失:Serverless Offline默认不会自动编译TypeScript,直接指向
.ts文件会导致依赖注入元数据丢失。 - 模块导出不完整:部分模块可能未正确导出服务,导致跨模块注入失败。
修复步骤
1. 修正模块导入配置
打开mcr\seguros-estado\src\seguros-estado.module.ts,将ErrorsService从imports数组移至providers数组:
@Module({ imports: [ TypeOrmModule.forRoot({ /* ...数据库配置 */ }), TypeOrmModule.forFeature([CitiesDane, InsuranceConfigurations, Fasecolda]), UtilsModule, LoggerModule, // 移除这里的 ErrorsService ], providers: [SegurosEstadoService, ErrorsService], // 添加到providers数组 controllers: [SegurosEstadoController], }) export class SegurosEstadoModule {}
2. 添加TypeScript编译支持
安装serverless-plugin-typescript插件以自动编译TS文件:
npm install serverless-plugin-typescript --save-dev
更新serverless.yml中的插件配置,并修改handler路径指向编译后的dist目录:
service: nestjs-microservices frameworkVersion: '4' provider: # ...其他配置 environment: NODE_ENV: production IS_OFFLINE: true # 添加环境变量标识离线模式 # ...其他环境变量 functions: segurosEstado: handler: dist/mcr/seguros-estado/src/main.handler # 指向编译后的文件 events: - http: path: seguros-estado/{proxy+} method: ANY cors: true plugins: - serverless-plugin-typescript # 先编译TS,再启动offline - serverless-offline custom: serverless-offline: httpPort: 3001 debug: true
3. 优化TS配置
更新tsconfig.json,确保编译输出和路径映射正确:
{ "compilerOptions": { "module": "commonjs", "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "ES2021", "sourceMap": true, "outDir": "./dist", "baseUrl": "./", "incremental": true, "skipLibCheck": true, "strictNullChecks": false, "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false, "paths": { "libs/*": ["libs/*"] }, "esModuleInterop": true // 解决CommonJS与ESM兼容问题 }, "include": ["mcr/**/*.ts", "libs/**/*.ts"], "exclude": ["node_modules", "dist"] }
4. 确保模块正确导出服务
检查LoggerModule是否正确导出LoggerService(类似UtilsModule的配置):
// libs/logger/logger.module.ts import { Module } from '@nestjs/common'; import { LoggerService } from './logger.service'; @Module({ providers: [LoggerService], exports: [LoggerService], // 必须导出才能被其他模块注入 }) export class LoggerModule {}
5. 优化Lambda handler逻辑
修改mcr\seguros-estado\src\main.ts,避免本地启动逻辑在离线模式下重复触发,并优化缓存:
import { NestFactory } from '@nestjs/core'; import serverlessExpress from '@vendia/serverless-express'; import { Handler } from 'aws-lambda'; import { SegurosEstadoModule } from './seguros-estado.module'; let cachedHandler: Handler; export const handler: Handler = async (event, context) => { context.callbackWaitsForEmptyEventLoop = false; // 防止Lambda进程挂起 if (!cachedHandler) { const app = await NestFactory.create(SegurosEstadoModule); await app.init(); const expressApp = app.getHttpAdapter().getInstance(); cachedHandler = serverlessExpress({ app: expressApp }); } return cachedHandler(event, context); }; // 仅在非生产、非离线模式下启动本地HTTP服务 if (process.env.NODE_ENV !== 'production' && !process.env.IS_OFFLINE) { (async () => { const app = await NestFactory.create(SegurosEstadoModule); const port = process.env.SEGUROS_ESTADO_PORT || 3001; await app.listen(port); console.log(`Microservicio Seguros Estado corriendo en http://localhost:${port}`); })(); }
验证修复
运行以下命令启动服务,测试依赖注入是否正常:
npx serverless offline
访问http://localhost:3001/dev/seguros-estado/test-r,确认不再抛出undefined错误。
内容的提问来源于stack exchange,提问作者andres martinez
相关产品推荐
相关产品推荐

