前言
使用 Angular 建立的網站是屬於 SPA (Single-Page Application) 單頁應用,是一種網路應用程式或網站的模型,它通過動態重寫目前頁面來與用戶互動,而非傳統的從伺服器重新載入整個新頁面。
雖然現在 Google 的爬蟲已經可以看得懂 SPA 架構的網站,但其他的搜尋引擎不見得看得懂,因此使用 SSR (Server Side Render) 技術來輔助網站的 SEO 還是必要的。
關於更詳細的名詞解釋可以參考 前後端分離與 SPA - Huli ,本文不會有太多著墨。
Angular Universal
其他前端主流框架如 React 或 Vue 對於 SPA 不利於 SEO 都有相關的解決辦法,如:
而 Angular 的解決方案就是使用 Angular Universal了。
在早期 Angular 要使用 SSR 技術似乎是相當麻煩的要修改很多地方,但現在卻可以使用少少的幾行指令就達成!而且幾乎是手把手照著 Angular 官網的步驟做,是不是相當友善呢~
建立新的空白專案
在終端機內輸入 ng new [projectName]
就可以建立起一個 Angular 的專案,這個示範中建立了 SSRDemo 專案。
加入 @nguniversal/express-engine 到專案中
在終端機輸入以下指令:
1 | ng add @nguniversal/express-engine --clientProject SSRDemo |
如此一來 Angular CLI 就會幫這個專案產生必要的檔案如: app.server.module.ts
。
不難看出 Angular CLI 幫我們做了相當多的事情,在早期這可是需要自己手動進行的而且不太容易。
運行 Universal Web 伺服器
所有的準備工作都已經就緒,可以在終端機輸入以下指令啟動伺服器:
1 | npm run build:ssr && npm run serve:ssr |
會得到乍看之下與尚未使用 SSR 技術前一樣的結果:
但實際上原始的程式碼內已經大不相同了!
不難看出有使用 SSR 技術的原始碼內多了不少內容,而這些內容就是要給搜尋引擎爬蟲看的。
在 HTTP 中使用絕對位置
在 Universal 應用中 HTTP 的 URL 必須是絕對位置,只有這樣 Universal 的 Web 伺服器才能處理那些請求。
這意味著當執行在伺服器端時,要使用絕對 URL 發起請求,而在瀏覽器中,則使用相對 URL。
在官網的 Angular 教學 (英雄範例) 中的服務都把請求送到了相對的 URL ,所以為了使其正常運作,需要額外建立 HttpInterceptor
,令其使用絕對 URL 發起請求。
建立 universal-interceptor.ts
1 | import {Injectable, Inject, Optional} from '@angular/core'; |
調整 app.server.module.ts
1 | import {HTTP_INTERCEPTORS} from '@angular/common/http'; |
現在當伺服器發起每個 HTTP 請求時,該攔截器都會被觸發,並把請求的 URL 替換為由 Express 的 Request 物件給出的絕對位置。
參考文件 & 程式碼
一開始還沒實作時看了蠻多篇文章的,但距今都有一定的時日了,在前端技術迭代的如此迅速的情況下,一篇幾年前的文章參考價值就不那麼高了,但對於了解整個脈絡還是很有幫助的,因此還是列出大致上看過那些文章:
- Angular 官方 - Universal
- IT 鐵人邦 - Angular Universal
- 保哥 - 如何在 Angular CLI 建立的專案加入 Angular Universal 伺服器渲染功能
程式碼
小結
結束了本篇的學習後,下一篇文章我們將試著將這份專案正式部屬到 Heroku 讓練習更加完整。