SuperAPI AI 工具集

cometchat-angular-v5-patterns

前端与建站

查看项目

更新于 10-21 20:28

技能介绍

用途

该技能是 CometChat Angular UI Kit 的“项目形态”胶水层,用于解决接入时的项目结构问题,而不是 CometChat API 本身的问题。当阻塞点在于 monorepo、NgModule、SSR 或配置存放位置时,应使用本技能。CometChat 的 API 表面属于 cometchat-angular-v5-core,任何符号可通过 cometchat-angular-v5-core/references/docs-map.md 获取;聊天页面的路由放置属于 cometchat-angular-v5-placement。

先检测项目形态

技能通过以下信号判断项目形态并给出差异点:

  • 存在 nx.json:Nx 工作区,差异在 env 文件、项目级样式、路径别名。
  • 存在 angular.json + src/main.ts:Angular CLI,默认形态,core 的配方可直接套用。
  • 存在 app.module.ts:NgModule 应用,组件需放入模块的 imports 数组。
  • 存在 server.ts / @angular/ssr:SSR / Universal,需要浏览器端守卫。

NgModule 而非 standalone

UI Kit 的组件是 standalone 的,因此 NgModule 应用需要把它们导入到模块的 imports 数组中,而不是 declarations。示例:

// app.module.ts
import { NgModule } from '@angular/core';
import { CometChatConversationsComponent, CometChatMessageListComponent } from '@cometchat/chat-uikit-angular';
import { ChatComponent } from './chat/chat.component';   // YOUR (non-standalone) component

@NgModule({
  declarations: [ChatComponent],
  imports: [CometChatConversationsComponent, CometChatMessageListComponent],
})
export class AppModule {}

不要把它们加入 declarations——它们不属于你声明,Angular 会报错。初始化也从 main.ts 移到模块上的 APP_INITIALIZER provider。

Nx 工作区

有三处变化:

  1. 环境文件位于应用项目下,例如 apps/<app>/src/environments/environment.ts。fileReplacements 放在该项目的 project.json 中,而不是根 angular.json。
  2. UI Kit 样式表在应用项目的 build styles 数组中注册,路径相对于工作区根:node_modules/@cometchat/chat-uikit-angular/styles/css-variables.css。
  3. 共享包装库可能重新导出 UI Kit 组件;重新导出的库也必须在其自身 imports 中列出这些组件,否则消费者会遇到静默不渲染。

Nx 完全不改变 CometChat API,只改变配置存放位置。

SSR / Angular Universal

UI Kit 是浏览器客户端。SDK 会接触 window、localStorage 和 WebSockets,这些在服务端都不存在。示例:

import { Component, inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { CometChatUIKit } from '@cometchat/chat-uikit-angular';
import { environment } from '../environments/environment';

@Component({ selector: 'app-root', standalone: true, template: '<router-outlet />' })
export class AppComponent {
  constructor() {
    if (isPlatformBrowser(inject(PLATFORM_ID))) {
      const { appId, region, authKey } = environment.cometchat;
      // init only in the browser — on the server this throws "window is not defined"
      CometChatUIKit.initFromSettings({
        appId, region,
        credentials: { authKey },
        chatSDK: { presenceSubscription: { type: 'ALL_USERS' } },
      });
    }
  }
}

规则:

  • 每个 init/login 调用都要用 isPlatformBrowser 守卫。
  • 聊天组件只在客户端渲染(hydration 上用 @defer,或基于浏览器标志的 *ngIf)。服务端渲染它们会产生立即不匹配的标记。
  • ThemeService 已经是 SSR 安全的——它通过 DOCUMENT token 写入 data-theme,而不是直接接触 document。
  • 不要尝试预渲染聊天路由;没有有意义的内容可预渲染。

注意:Angular UI Kit 文档未覆盖 SSR / Angular Universal。上述守卫是根据 SDK 所接触的内容(window、localStorage、WebSockets)推导出来的,属于本技能包自身的指导——文档中未提及并不代表它们不必要。

懒加载聊天路由

{ path: 'chat', loadComponent: () => import('./chat/chat.component').then(m => m.ChatComponent) }

懒加载路由是可行且推荐的——UI Kit 体积较大。初始化仍在 bootstrap 时执行一次,而不是在懒加载 chunk 中,否则首次导航会付出代价,第二次导航会重复执行。

状态——signals 或 RxJS,二选一

ChatStateService 同时暴露两者(activeUser signal、activeUser$ observable)。每个组件选择一种风格并保持一致;混用会导致同一值出现两条更新路径。

  • 模板中使用 signals:无需订阅、无需清理、无需 async pipe。
  • 与其他流组合时使用 observables:始终在 ngOnDestroy 中 takeUntil(destroy$)。
  • 不要把任一者镜像到自己的字段中——参见 placement 的“两个真相来源”陷阱。

常见陷阱

  • UI Kit 组件放入 declarations → Angular 报错;它们属于 imports。
  • SSR 下未守卫的 init → 构建或首次请求时 window is not defined。
  • init 放在懒加载 chunk 内 → 执行过晚,或执行两次。
  • Nx:在 工作区根编辑 env/styles → 静默无效;它们属于应用项目。
  • 同一值同时使用 signals 和 observables → 两条更新路径,UI 漂移。

验证是否生效

ng build(以及适用时的 ng build --ssr)通过 · 聊天在浏览器中渲染 · 服务端无 window is not defined · 导航到懒加载路由一次只初始化一次 · 配置在你构建的每种 configuration 中都能解析。