关键词搜索

源码搜索 ×
×

SAP Spartacus一个客户项目无法启用SSR服务器端渲染的实际例子和分析方法

发布2021-01-28浏览488次

详情内容

Customer support - SSR not working

Main problem

In the codebase I found multiple instances of access to properties inside this.windowRef.nativeWindow.

This works correctly on client side, but on server side (SSR) nativeWindow is undefined.

Recommendation

Always validate if the code is executing in browser or on the server.

Best practice

Use PLATFORM_ID with utility isPlatformBrowser to detect if you can safely access nativeWindow. Alternatively check if nativeWindow is defined.

Example:

import { isPlatformBrowser } from '@angular/common';
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { WindowRef } from '@spartacus/core';

@Injectable({
  providedIn: 'root',
})
export class SomeService {
  constructor(
    protected winRef: WindowRef,
    @Inject(PLATFORM_ID) protected platform: any
  ) {}

  loadDataLayer(): void {
    // Only load data layer on client side (no SSR)
    if (isPlatformBrowser(this.platform)) {
      this.winRef.nativeWindow.diablo?.loadDataLayer();
    }
  }
}

    Files to fix

    Completely breaking SSR:

    • digital-data.adapter.ts
    • custom-occ-cms-page-normalizer.ts

    Additionally search for any usage of nativeWindow and check if it is accessed safely.

    How to speed up debugging?

    Fix script dev:ssr.

    Add to architect in angular.json

    "serve-ssr": {
      "builder": "@nguniversal/builders:ssr-dev-server",
      "options": {
        "browserTarget": "spartacusstore:build",
        "serverTarget": "spartacusstore:server"
      },
      "configurations": {
        "production": {
          "browserTarget": "spartacusstore:build:production",
          "serverTarget": "spartacusstore:server:production"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Other issues

    There are other kind of access to browser API without using WindowRef.nativeWindow. Eg. sessionStorage, screen, localStorage. Same rule mentioned above applies here. It’s always better to check if you can execute such code (not doing it in SSR).

    What we will improve in Spartacus

    To make it more clear to everyone that nativeWindow is not always available we will fix TS types for nativeWindow to indicate that it can be undefined along with TSDoc comment documenting that it can be undefined and how to check if you can use it.

    也可以参考这个文档,进行SAP Spartacus SSR的调试:

    How to Debug a Server–Side Rendered Storefront

    2021-1-29 4:16PM 更新

    We found out that the problem was caused by using this.windowAdapter.getWindow().sessionStorage.* without previously checking if the sessionStorage is actually available. In SSR it was undefined.

    If you wrap all the calls in an if (this.windowAdapter.getWindow().sessionStorage) {...} the PLP pages are being SSRed correctly.

    As an additional, browser’s storage (sessionStorage, localStorage) API is not available in SSR, therefore code defensively.

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载