SSR 浏览器/服务器/应用程序的 Angular 通用模块拆分

发布时间:2021-03-08 17:16

我遇到了 Angular Universal 投掷问题:

ERROR ReferenceError: document is not defined

这是 Fullcalendar 模块,它试图访问服务器端的文档,而服务器上不存在该文档。我想做的是遵循来自 https://github.com/angular/universal/blob/master/docs/gotchas.md 的 Angular Git hub 的指导方针,说:

<块引用>

如果您有第三方提供的非通用兼容的组件,您可以为浏览器和服务器创建两个单独的模块(您应该已经拥有的服务器模块),此外到您的基本应用程序模块。基本应用程序模块将包含所有与平台无关的代码,浏览器模块将包含所有特定于浏览器/与服务器不兼容的代码,反之亦然。为了避免编辑太多模板代码,可以为库组件创建一个无操作组件

我已经创建了浏览器模块:

 import { NgModule } from '@angular/core';
 import { AppComponent } from './app.component';
 import { AppModule } from './app.module';
 import { CalendarModule } from './calendar/calendar.module';

 @NgModule({

 imports: [
   AppModule,
   CalendarModule // <---- this module will include the code that must only run on the browser
 ],
 bootstrap: [AppComponent]

})
export class AppBrowserModule { }

现在我不知道我应该修改哪些其他文件才能制作:

  • app.module.ts 仅与平台无关的代码(可以导入到服务器/浏览器模块的共享模块)
  • server.module.ts 仅服务器端代码(可以 ssr'ed)
  • browser.module.ts 包含所有平台无关代码和浏览器代码(例如 fullcalendar 模块
回答1

我把事情复杂化了。为了避免在服务器端使用浏览器 api,我简单地将 FullCalendar 组件包装在 ng-template 中,如下所示:

在构造函数中将 isBrowser 设置为 isPlatformBrowser

 constructor(
   @Inject(PLATFORM_ID) private platformId,
   private eventService: EventsService, 
   private router: Router){
     this.isBrowser = isPlatformBrowser(this.platformId);
     console.log(this.isBrowser)
  }

并在模板中:

<ng-container *ngIf="isBrowser">
    <full-calendar [options]="calendarOptions"></full-calendar>
 </ng-container>