简体   繁体   English

Angular 9 通用服务器端渲染 (SSR) 错误 HTMLCanvasElement

[英]Angular 9 universal Server side rendering (SSR) error HTMLCanvasElement

Error: NotYetImplemented
    at HTMLCanvasElement.Wo4J.exports.nyi (/path/server/main.js:1:3906285)
    at rj.nf (/path/server/main.js:1:1929447)
    at /path/server/main.js:1:1930713
    at Object.ADia (/path/server/main.js:1:2061225)
    at __webpack_require__ (/path/server/main.js:1:295)
    at Object.7PEY (/path/server/main.js:1:1216808)
    at __webpack_require__ (/path/sen3aPro/server/main.js:1:295)
    at Object.d2mR (/path/server/main.js:1:5425768)
    at __webpack_require__ (/path/server/main.js:1:295)
    at Object.ZAI4 (/path/server/main.js:1:3975117)

i am geeting this error angular 9 server side rendering i am using open street map (OSM) and i think ngx-openlayers causes this problem cause when i remove it i got no error我收到此错误 angular 9 服务器端渲染我正在使用开放街道 map (OSM),我认为ngx-openlayers会导致此问题,因为当我删除它时我没有错误

I tried to load AngularOpenlayersModule module and the component using this module on client side only but no luck我尝试仅在客户端加载AngularOpenlayersModule模块和使用此模块的组件,但没有运气

my SharedModule.ts :我的SharedModule.ts

import {NgModule, PLATFORM_ID} from '@angular/core';
import {OsmViewComponent} from './osm-view/osm-view.component';
import {AngularOpenlayersModule} from 'ngx-openlayers';
import {CommonModule, isPlatformBrowser} from '@angular/common';

let osmC = [];
let ol = [];
if (isPlatformBrowser(PLATFORM_ID)) {
  osmC = [OsmViewComponent];
  ol = [AngularOpenlayersModule];
}

@NgModule({
  imports: [
    CommonModule,
    AngularOpenlayersModule
  ],
  declarations: [
    OsmViewComponent
  ],
exports: [
  OsmViewComponent
],
})
export class SharedModule {}

my dependencies are:我的依赖是:

  "dependencies": {
    "@angular/animations": "~9.0.3",
    "@angular/cdk": "^9.1.2",
    "@angular/common": "~9.0.3",
    "@angular/compiler": "~9.1.3",
    "@angular/core": "~9.1.3",
    "@angular/fire": "^5.4.0",
    "@angular/forms": "~9.0.3",
    "@angular/platform-browser": "~9.0.3",
    "@angular/platform-browser-dynamic": "~9.0.3",
    "@angular/router": "~9.0.3",
    "@auth0/angular-jwt": "^4.2.0",
    "@fortawesome/fontawesome-free": "^5.12.1",
    "@types/chart.js": "^2.9.15",
    "animate.css": "^3.7.2",
    "boostrap": "^2.0.0",
    "bootstrap": "^4.1.3",
    "chart.js": "^2.9.3",
    "easy-pie-chart": "^2.1.7",
    "firebase": "^7.14.4",
    "get-blob-duration": "^1.1.0",
    "hammerjs": "^2.0.8",
    "lodash": "^4.17.15",
    "mdbootstrap": "^4.14.0",
    "ng-circle-progress": "^1.5.1",
    "ng-uikit-pro-standard": "file:ng-uikit-pro-standard-9.0.0.tgz",
    "ng2-charts": "^2.3.0",
    "ng5-slider": "^1.2.4",
    "ngx-device-detector": "^1.4.2",
    "ngx-openlayers": "^1.0.0-next.15",
    "ol": "^6.3.1",
    "openlayers": "^4.6.5",
    "recordrtc": "^5.5.9",
    "rxjs": "~6.5.4",
    "screenfull": "^3.3.0",
    "tslib": "^1.10.0",
    "units-converter": "^1.0.2",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.900.4",
    "@angular/cli": "~9.1.3",
    "@angular/compiler-cli": "~9.1.3",
    "@angular/language-service": "~9.0.3",
    "@types/node": "^12.11.1",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "protractor": "~5.4.3",
    "ts-node": "~8.3.0",
    "tslint": "~5.18.0",
    "typescript": "~3.7.5"
  }

Like I indicated with in this answer , open layers relies on the pixelworks lib, which tries to create a canvas element when the lib is imported (even if you are not actually instantiating an open layers map).就像我在这个答案中指出的那样,开放层依赖于pixelworks库,它会在导入库时尝试创建 canvas 元素(即使您实际上并未实例化开放层映射)。 This will not work server side and will cause the SSR process to crash这在服务器端不起作用,会导致 SSR 进程崩溃

My hack, based on the fact that I did not need to render the map server side, was to modify the server.js file (or main.js for angular 9+) to remove the offending bit of code基于我不需要渲染 map 服务器端这一事实,我的 hack 是修改server.js文件(或main.js 9+ 的 main.js)以删除有问题的代码位

sed -i "s/var context = document.createElement('canvas').getContext('2d');/var context = null;/" dist/server.js

This will allow code execution to continue server side.这将允许代码执行继续服务器端。 The map will be initiated only in the browser, when the client side angular application takes over.当客户端 angular 应用程序接管时,map 将仅在浏览器中启动。

In the component creating the map, you can also check if you are executing the code client or server side to only instantiate the map client side, using isPlatformbrowser在创建 map 的组件中,您还可以使用 isPlatformbrowser 检查您是在执行代码客户端还是服务器端仅实例化isPlatformbrowser客户端

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM