最近專案要從 SPA 改成 SSR,雖然一般而言 SSR 是在專案開發前或者開發初期就得考量,但是事情總有個萬一,俗話說的好,需求是會成長的?總之好險 Quasar 有提供建構 SSR 的方法,這對於轉換到 SSR 會減少許多麻煩。
新增 SSR 模式
透過 Quasar CLI 我們幾乎可以直接用 SPA 程式碼打造出一份 SSR 的程式碼,我們先把 SSR 模式加進去,再來看後續怎麼處理吧!
- 首先輸入
quasar mode add ssr
幫我們的 Quasar 專案加上 SSR 模式 - 成功新增模式後,透過
quasar dev -m ssr
運行專案 - 順利執行後,專案底下會多出一個名為
src-ssr
的資料夾,裡面的檔案基本上使用預設的設定即可
使用 SSR 的注意事項
轉換成 SSR 模式後,首先就是要注意 SSR 與 SPA 的不同,這裡也可以參考 Vue 官方寫的 Vue SSR Guide,因為 Quasar SSR 就是基於 Vue SSR 去做包裝之後的應用。
舉例來說,透過 SSR 模式開啟網頁的話,Lifecycle 裡面的 Hooks 只有 beforeCreate
與 created
會有作用,因此我們寫在這兩個 Hooks 以外的程式碼,都需要考慮到是否會造成影響。
加入 PreFetch 機制
每當有人點開我們的 SSR 網站時,會類似於進入一個已經抓取好資訊的網頁,而這些資料我們會用 Vuex 來預先儲存起來。這個預存的動作就是 PreFetch
,如果想要使用 PreFetch
預存資料,我們需要在 Quasar 設定檔案中加入以下程式碼。
// quasar.conf.js
return {
preFetch: true,
};
使用時要注意,其實 Quasar 在 Server 與 Client 環境下都會觸發 preFetch
再接著執行 created
。
因此,如果我們有些內容需要在畫面渲染之前,就透過呼叫 API 等方式呈現給 Server 看的話,我們會使用到 PreFetch
這個 Hook 來率先取得資訊,而非使用 created
。
另外,在使用 PreFetch
時因為不能使用 this
來存取資料,所以如果想要使用 data
裡面的某些變數,可以將它們改為存放在 Vuex,這樣就能在 PreFetch
中使用這些資料哩。
// 這是一個被設定為路由的 .vue 檔案
async created() {
if (process.env.SERVER) {
return;
}
if (!this.isPreFetch) {
await this.$store.dispatch(
'store-name/fetchDataById',
this.$route.params.uid,
);
}
},
async preFetch({ store, currentRoute }) {
if (process.env.CLIENT) {
return;
}
await store.dispatch(
'store-name/fetchDataById',
currentRoute.params.uid,
);
},
上述範例程式碼中,我新增 process.env
去判斷 Server 與 Client 環境,因為我在兩個 Hook 所執行的動作是相同的,差別只在是否要給 Server 預存。如果是 Server 環境,那我就只會執行 preFetch
這個 Hook;如果是 Client 環境,就只會執行 created
的 Hook。
另外,preFetch
只會被路由檔案 (src/router/routes.js
) 中直接設定的元件觸發,元件內使用到的子元件是不會觸發 preFetch
的。
SEO 設定
SEO 應該是我們會從 SPA 改為 SSR 的主要原因之一,像是某些頁面或是某個商品想要被分享出去,而分享時所呈現的連結資訊就得靠 SSR 去提供,像是縮圖、標題、敘述、網址……等內容。
藉由 Quasar CLI 的插件 Quasar Meta Plugin,我們能夠動態地將 HTML 的 <meta>
標籤放入頁面的 DOM 元素中。
舉個例子,我們可以直接在 .vue
檔案加入 meta
這個屬性,並且可以使用 data
裡的資料,來組合出我們想要呈現的 Meta 資訊,以下提供一個簡單的範例。
// Product.vue
export default {
data() {
return {
title: "商品頁面",
};
},
meta() {
return {
meta: {
description: {
name: "description",
content: `網站描述 - ${this.data.content}`,
},
ogTitle: {
name: "og:title",
content: `${this.data.subtitle} - ${this.data.title}`,
},
ogDescription: {
name: "og:description",
content: this.data.content,
},
ogImage: {
name: "og:image",
content: this.data.image,
},
ogUrl: {
name: "og:url",
content: this.$route.fullpath,
},
},
};
},
};
設定完成後,你可以透過 Meta Tags 這個網站進行測試並預覽呈現結果。
以上就是這次使用 Quasar SSR 的過程,主要就是加上 SSR 模式、PreFetch 機制、SEO 設定,以及轉移資料至 Vuex 等等。其中,把元件資料轉移至 Vuex,與各個元件 Hook 的修改會比較麻煩,以我個人而言更動還滿多的 😅,或許是專案規模比較龐大一些。
此外,我自己還有出現一些比較難解決的錯誤,像是 HTML 結構 Client Side Hydration 的問題等等,但是這跟我個人的寫法比較有關係,所以這邊就沒有提到哩。
以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫