带有Nrwl / Nx的Angular SSR-外部库调用document.getElementById

时间:2019-12-20 14:36:55

标签: angular plotly server-side-rendering angular-universal

在当前项目中,我正在Nrwl / Nx工作区上实现Angular服务器端渲染。我严格遵循Nrwl的这些guidelines。一切正常,直到运行节点应用程序。该项目包含一个名为Plotly.js的外部库,不幸的是使用了document。它引发以下错误

/Users/PATHTOPROJECT/node_modules/plotly.js/dist/plotly.js:105975
    var style = document.getElementById(id);
                ^
ReferenceError: document is not defined

Plotly.js导入到延迟加载的NgModule

import * as PlotlyJS from 'plotly.js/dist/plotly.js';
import { PlotlyModule } from 'angular-plotly.js';
PlotlyModule.plotlyjs = PlotlyJS;

当然在SSR中document不可用。 Plotly.js仅在延迟加载的路由中使用。我试图保护此路由仅在isPlatformBrowser上可用,但这不能解决问题。也许可以添加“假” document之类的东西吗?

您有什么想法吗?谢谢,加油!

1 个答案:

答案 0 :(得分:0)

您最需要的是:https://github.com/angular/angular/blob/9b9116c79d626b6356f3dfe0d48c9d990ac412a2/packages/platform-browser/src/browser.ts#L100

但我有经验的人向您展示如何制作自定义BrowserModule.withServerTransition(),您可以阅读文档并亲自尝试。

在这里您可以解决如何使用ngAfterViewInit()https://stackoverflow.com/a/51150552/6310260

将库导入组件的过程

因为您想操纵样式。这是它将在SSR上运行的一种方式:

模板:

<div [ngStyle]="setStyle(item.img)"></div>

component.ts

setStyle(imgUrl: string) {
    return {
      'background-image': `url('${imgUrl}')`,
      'background-position': 'center',
      'background-repeat': 'no-repeat',
      'background-size': 'cover'
    }
  }

第二个:尝试“生命周期挂钩” ngAfterViewInit()