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

使用Angular Material(MatBottomSheet)与SSR时AWS Lambda超时问题求助

解决Angular SSR部署Lambda时MatBottomSheet注入导致的超时问题

我之前也踩过类似的Angular SSR + Lambda + Material组件的坑,结合你的描述,问题的核心在于MatBottomSheet是依赖浏览器DOM环境的客户端组件,当在SSR的Node环境中注入它时,会触发一些只能在浏览器中运行的初始化逻辑,导致Lambda进程卡住,最终超时(哪怕你调长了超时时间,这种卡住是无限等待,所以还是会超时)。

下面是几个经过验证的解决方案,按优先级排序:

1. 条件注入MatBottomSheet(最直接)

在组件或模块中通过PLATFORM_ID判断当前环境,只在浏览器端注入真实的MatBottomSheet,SSR环境下提供一个空实现。

方法一:组件内动态处理

import { Component, Inject, PLATFORM_ID, Injector } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { MatBottomSheet } from '@angular/material/bottom-sheet';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html'
})
export class YourComponent {
  private bottomSheetService: MatBottomSheet | null = null;

  constructor(
    @Inject(PLATFORM_ID) private platformId: Object,
    private injector: Injector
  ) {
    // 仅在浏览器环境中获取真实的MatBottomSheet实例
    if (isPlatformBrowser(this.platformId)) {
      this.bottomSheetService = this.injector.get(MatBottomSheet);
    }
  }

  openBottomSheet() {
    if (this.bottomSheetService) {
      this.bottomSheetService.open(YourBottomSheetComponent);
    }
    // SSR环境下可以做个空操作,或者提示用户在浏览器中使用
  }
}

方法二:模块层面配置工厂提供者(更优雅)

在你的Feature模块中配置一个工厂提供者,统一处理环境判断,组件无需关心环境:

import { NgModule, Injector, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { MatBottomSheet } from '@angular/material/bottom-sheet';

// 定义一个兼容SSR的空实现
class MockBottomSheet {
  open() {
    return { dismiss: () => {} };
  }
}

// 工厂函数:根据环境返回真实服务或空实现
export function bottomSheetFactory(injector: Injector, platformId: Object) {
  if (isPlatformBrowser(platformId)) {
    return injector.get(MatBottomSheet);
  }
  return new MockBottomSheet();
}

@NgModule({
  providers: [
    {
      provide: MatBottomSheet,
      useFactory: bottomSheetFactory,
      deps: [Injector, PLATFORM_ID]
    }
  ]
})
export class YourFeatureModule {}

2. 调整Serverless Webpack配置

确保Webpack打包SSR代码时,排除掉仅浏览器端依赖的模块,或者明确指定target为node,避免打包浏览器环境的polyfill:

在webpack.config.js中:

module.exports = {
  target: 'node', // 明确打包为Node环境可用的代码
  externals: [
    // 排除Angular Material中依赖DOM的模块(按需调整)
    /@angular\/material\/bottom-sheet/
  ]
};

注意:这种方式需要配合条件注入使用,否则组件导入MatBottomSheet时会报错找不到模块。

3. 排查Lambda日志的隐藏错误

有时候超时只是表象,背后可能有未捕获的异常导致进程挂起。你可以:

  • 打开Lambda的CloudWatch日志,查看是否有UnhandledPromiseRejection或模块加载错误
  • 在SSR的Express服务器代码中添加全局错误捕获:
app.use((err: any, req: any, res: any, next: any) => {
  console.error('SSR Error:', err);
  res.status(500).send('Server Error');
});

为什么本地运行正常?

本地开发或生产构建后本地运行时,SSR服务器和浏览器是在同一环境(你的电脑),即使注入MatBottomSheet,浏览器端的代码会接管,而Lambda是纯Node环境,没有DOM,所以会卡住。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:55