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

NestJS部署AWS Lambda后依赖注入失效,HttpService/AiManagerService为undefined

NestJS部署AWS Lambda后依赖注入失效问题排查与解决

我正在开发一个基于设备、食材和限制列表生成食谱的项目,使用NestJS结合Axios发起HTTP请求。本地运行完全正常,但通过AWS CDK部署到Lambda后,日志显示依赖注入的AiManagerService、HttpService均为undefined,报错信息为TypeError: Cannot read properties of undefined (reading 'buildRecipe')。

核心代码片段

AppModule

@Module({
    imports: [AiManagerModule, HttpModule.register({}),],
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {
}

自定义模块AiManagerModule

@Module({
  controllers: [AiManagerController],
  providers: [AiManagerService],
  imports: [HttpModule]
})
export class AiManagerModule { }

自定义控制器AiManagerController

@Controller('ai-manager')
export class AiManagerController {
  constructor(private readonly service: AiManagerService) {
    // AWS日志中this.service为undefined,本地正常
    console.log('AiManagerController constructor HttpService: ', this.service); 
  }

  @Post('create-recipe')
  async generate(
    @Body() body: CreateRecipesRequestBody,
  ): Promise<BaseResponseBody<RecipeResponseBody[]>> {
    console.log('create recipe body',  body);

    // AWS日志中this.service为undefined,本地正常
    console.log('create recipe service',  this.service);

    let ingredients = body.ingredientList;
    let equipements = body.equipmentList;
    let restrictions = body.restrictionList;

    //报错行
    let result = await this.service.buildRecipe(
      'pt-br',
      ingredients,
      equipements,
      restrictions,
      false,
    );
    console.log('create recipe result', result);
    return BaseResponseBody.success(result);
  }
}

自定义服务AiManagerService

@Injectable()
export class AiManagerService {
  constructor(private readonly service: HttpService) {
    // AWS日志中this.service为undefined,本地正常
    console.log('AiManagerService constructor HttpService: ', this.service);
  }

  async buildRecipe(
    lang: string,
    ingredients: string[],
    equipements: string[],
    restrictions?: string[],
    shouldAddOptionals?: boolean,
  ): Promise<RecipeResponseBody[]> {
           //通过prompt发起axios请求等逻辑...
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2023",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "noFallthroughCasesInSwitch": false
  }
}

Lambda配置(CDK)

const nestJsLambda = new NodejsFunction(this, 'LAMBDANAMEHERE', {
      runtime: lambda.Runtime.NODEJS_22_X,
      memorySize: 512,
      timeout: cdk.Duration.seconds(10),
      handler: 'handler',
      entry: entryFile,
      projectRoot: simpleAppRoot,
      depsLockFilePath: lockFilePath,
      bundling: {
        minify: false,
        externalModules: [
          '@nestjs/microservices',
          '@nestjs/websockets/socket-module',
        ],
        nodeModules: [
          '@nestjs/common',
          '@nestjs/axios',
          'axios'
        ],
        environment: {
          NODE_ENV: 'production',
        }
      },
      environment: {
      },
    });

已做排查

  • 多次检查依赖注入,服务已添加@Injectable注解,模块导入正确
  • 本地运行完全正常
  • 尝试调整Lambda配置中nodeModules列表,无效
  • cdk synth和cdk deploy无警告或错误

解决方案

1. 修正Lambda入口文件的NestJS初始化逻辑

确保Lambda入口通过NestJS的Express适配器正确初始化应用上下文,避免直接导出控制器方法导致依赖注入失效。示例入口代码:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Handler, Context } from 'aws-lambda';
import { ExpressAdapter } from '@nestjs/platform-express';
import * as express from 'express';

let cachedServer: Handler;

export const handler: Handler = async (event: any, context: Context) => {
  if (!cachedServer) {
    const expressApp = express();
    const adapter = new ExpressAdapter(expressApp);
    const app = await NestFactory.create(AppModule, adapter);
    app.enableCors();
    await app.init();
    cachedServer = expressApp;
  }
  return cachedServer(event, context);
};

2. 调整CDK打包配置,禁用树摇并优化依赖处理

Lambda打包时的树摇机制可能会移除NestJS依赖注入所需的装饰器元数据,修改打包配置:

bundling: {
  minify: false,
  treeShake: false, // 禁用树摇,保留元数据
  externalModules: [
    '@nestjs/microservices',
    '@nestjs/websockets/socket-module',
  ],
  // 移除手动指定nodeModules的配置,让CDK自动处理所有依赖,避免遗漏元数据相关依赖
  environment: {
    NODE_ENV: 'production',
  }
},

3. 明确指定tsconfig文件路径

在CDK配置中明确指定tsconfig路径,确保打包时应用正确的装饰器元数据编译选项:

const nestJsLambda = new NodejsFunction(this, 'LAMBDANAMEHERE', {
  // ...其他配置
  tsconfig: './tsconfig.json',
});

4. 验证依赖版本兼容性

确认@nestjs/core、@nestjs/axios、aws-cdk-lib等依赖版本相互兼容,使用npm ci确保部署环境与本地依赖版本完全一致,避免因版本不匹配导致的反射元数据丢失。

5. 避免直接引用控制器/服务实例

确保Lambda入口不直接引用控制器或服务的方法,必须通过NestJS应用上下文获取实例,否则依赖注入容器无法正常初始化依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:22:33