1

我使用我的角4服務器端渲染應用simpleMDE編輯器並獲得textarea的參考使用的ReferenceError:導航不angular4與服務器端渲染

@ViewChild('simpleMDE') textarea : ElementRef; 

和ngAfterViewInit初始化它定義()

this.simplemde = new SimpleMDE(
     { 
      element: this.textarea.nativeElement.value, 
     }) 
在模板

在正在使用的textarea這樣

<textarea id="simpleMDE" #simpleMDE></textarea> 

雖然啓動服務器其投擲錯誤說

projectpath\node_modules\codemirror\lib\codemirror.js:11 
     typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 
                       ^
ReferenceError: navigator is not defined 
    at projectpath\node_modules\codemirror\lib\codemirror.js:18:17 

請建議的東西,我卡在這裏。 GitHub Repo

回答

2

如角通用文檔

窗口,文檔,導航和其他瀏覽器類型的說明 - 不存在於服務器上 - 這樣使用它們,或任何使用它們(jQuery的舉例)庫將不工作

如果您需要使用它們,請考慮將它們限制爲只有您的客戶端,並以環境方式包裝它們。您可以使用通過PLATFORM_ID標記注入的Object來檢查當前平臺是瀏覽器還是服務器。

import { PLATFORM_ID } from '@angular/core'; 
import { isPlatformBrowser, isPlatformServer } from '@angular/common'; 

constructor(@Inject(PLATFORM_ID) private platformId: Object) { ... } 

ngOnInit() { 
    if (isPlatformBrowser(this.platformId)) { 
     // Client only code. 
     ... 
    } 
    if (isPlatformServer(this.platformId)) { 
    // Server only code. 
    ... 
    } 
} 

將需要操縱庫:(

編輯: 在以下幾行錯誤來自codemirror.js

var userAgent = navigator.userAgent; 
var platform = navigator.platform; 

試圖操縱代碼

if(navigator){ 
    var userAgent = navigator.userAgent; 
    var platform = navigator.platform; 
}else{ 
var userAgent="server"; 
var platform="server"; 
} 

PS :不知道會有什麼影響:D。

+0

我沒有在手工代碼中的任何地方使用它,但simpleMDE texteditor在內部使用它,所以可能從那裏引發它的拋出錯誤。 只要我會回到我的機器,我會盡快解決您的問題。 感謝男人.... !! –

+0

@PraveenRana請參閱編輯答案,不確定是否有助於解決問題。 –

+0

好的,Parth。我會測試這段代碼,並讓你知道這是否有效。 只能在晚上測試。 –

1

猜你在js/ts文件中有這樣的代碼。

import CodeMirror from 'codemirror'; 

如回答@Parth Ghiya,navigator只在瀏覽器覆蓋義齒,這將導致錯誤。

在試圖支持服務器渲染,你可以做一些改變(懶惰的要求)在你的代碼是這樣的:

// just before places where are using codemirror 
const CodeMirror = require('codemirror'); 
require('codemirror/addon/hint/show-hint'); 

CodeMirror(...) 
+0

你可以看看存儲庫,請https://github.com/ranavc32/SimpleMDE- angular-universal –

+0

@PraveenRana對'simplemde'的依賴似乎使用'codemirror',並且我沒有發現任何服務器渲染問題超越或確切地說支持angular-universal的任何單詞。如果你仍然想用'angular-universal'來使用它,你應該像我對'simplemde'庫所回答的那樣進行修改。 – Pengyy

+0

您可以根據您所說的更改向存儲庫發出拉取請求,因爲我不知道在哪裏以及我需要做什麼改變,將會非常有必要。 謝謝。 –

0

這是我如何處理這個問題八九不離十。 對我來說,服務器渲染僅用於SEO目的。而像codemirror之類的東西並沒有對SEO做任何事情。因此,我的方法是「不要在服務器端渲染它」。

enter image description hereref

基本結構是像上面圖。

您有2個啓動文件,一個用於服務器渲染,另一個用於客戶端渲染。

因此,實際上每個啓動文件都可以有不同的應用程序模塊。

在用於服務器渲染的應用程序模塊中,可以使用模擬組件替換使用瀏覽器對象的組件,並將真實組件用於客戶端。

這樣你就不用擔心服務器渲染中有問題的組件。

另一種解決方案是使用webpack處理這些瀏覽器對象。

像這樣ref

module: { 
    rules: [ 
    { 
     test: /@angular(\\|\/)material/, use: "imports-loader?window=>global,CSS=>null,navigator=>{get userAgent(){return Zone.current.get('req')['headers']['user-agent'];}}" 
    } 
    ] 
} 

就個人而言,我更喜歡第一個解決方案。第二個是有點hacky對我來說,渲染一個組件與服務器端的搜索引擎沒有任何關係,並不真的給我們帶來任何好處。