開源 | UMajs框架vue-ssr同構最佳實踐方案

語言: CN / TW / HK

01

簡介

在6月底 ,UMajs釋出了和React技術棧進行同構的外掛方案(@umajs/plugin-react-ssr)。 使得開發者可以快速方便的使用UMajs快速構建web應用,而這次UMajs帶來了和Vue結合使用的同構方案,支援SSR和CSR。使用方式也近乎100%保持和React外掛一致 。對@umajs/plugin-react-ssr還不了 解的同學請檢視末尾往期文章。 Umajs框架react-ssr同構最佳實踐

02

外掛介紹(@umajs/plugin-vue-ssr)

plugin-vue-ssr外掛擴充套件了UMajs中提供的統一返回處理Result物件,新增了Result.vue頁面元件渲染方法,可在controller自由呼叫,不限制服務端頁面路由;使用類似傳統模板引擎。也同時將方法掛載到了 koa 中介軟體中的ctx物件上;當一些公關的頁面元件,比如 404、異常提示頁面、登入或者需要在中介軟體中攔截跳轉時可以在mid dleware中呼叫

特性

  • 不預設路由,不需區分前端路由和後端路由概念,且支援頁面級元件 AB 測;靈活
  • 頁面元件中沒有__isBrowser__之類變數對ssr和csr模式進行特殊區分處理;統一。
  • 自定義HTML採用htmlWebpackPlugin,沒有runtime,頁面響應速度更高;高效能。
  • 支援html中支援模板插值,可實現特殊場景SEO;易上手。
  • 頁面開發不依賴框架包裝的任何模組,保持原生的vue開發體驗;友好,易升級。
  • 資料獲取提供服務端注入方式,頁面檢視渲染和資料加工分開處理;邏輯更清晰。
  • 支援SSR和CSR動態調整,支援SSR快取,降級。高可用。
  • 支援其他koa開發框架使用。可擴充套件。
  • 支援 MPA,各頁面組 件可單獨構建,頁面級更新。

外掛使用

手動引入外掛

1、外掛安裝
yarn add @umajs/plugin-vue-ssr --save
2、 開啟 package.json 檔案並新增 scripts 配置段:
start 啟動你的 node 專案
  • build 執行npx ssr build構建用於生產環境的應用程式,專案支援多專案工程目錄結構,可通過指定頁面標識單獨構建或者啟動特定頁面,命令為:npm run build xxx
  • analyzer 執行npx ssr analyzer 用於分析頁面元件打包依賴分析 可通過 npm run analyzer xxx xxx 為頁面元件標識,可指定分析某個頁面元件打包結果
3、配置外掛
4、建立Pages目錄和頁面元件
框架預設配置屬性rootDir預設為根目錄下web,pages 下是頁面元件入口,比如index頁面,vue 主入口檔案為index/index.js,頁面元件為index/App.vue。
└── web    └── pages        └── index            ├── App.vue            ├── index.js            ├── index.html (非必須)

cli工具初始化vue-ssr模板工程 【推薦】

在 cli 中支援快速建立umajs-vue-ssr模板工程。
安裝和啟動
cd umajs-vue-demoyarn installyarn start

路由使用

外掛擴充套件了Umajs中提供的統一返回處理Result方法,新增了vue頁面元件可在controller自由呼叫,方式類似傳統模板引擎使用方法;也同時將方法掛載到了 koa 中介軟體中的ctx物件上;當一些公關的頁面元件,比如 404、異常提示頁面、登入或者需要在中介軟體中攔截跳轉時可以在middleware中呼叫。

外掛API

如果 options 引數傳遞為空 則預設會使用全域性配置屬性,全域性配置採用外掛整合時傳遞的 options 引數
注意 cache只在生產環境開啟有效。
接下來介紹在Umajs同構方案中如何編寫Vue的元件以及一些使用技巧。


03

頁面元件

APP.vue主頁面元件

indes.js主入口檔案

Pages下按照資料夾名稱定義 vue 頁面元件,每一個頁面元件必須包含inde.js主入口檔案,檔案必須匯出元件App。如果使用vue-router,則將路由配置匯出為Router物件;當使用vuex時,則將初始化配置匯出為Store。
至此,我們就可以在Umajs服務端路由中通過外掛提供的Result.vue api指定渲染到我新建立的App.vue。相信你還想繼續瞭解下去…


04

資料獲取

在Pages頁面中,vue 頁面元件獲取資料有兩種形式;我們分為服務端直出資料(Props 和 State)和 vue 元件靜態方法asyncData獲取兩種形式。我們可以通過這兩種方式對服務端渲染時首次頁面渲染進行資料填充,使得服務端渲染時能返回完整的 DOM 結構,提高使用者體驗和更利於SEO。

服務端直出 Props[推薦]

框架在服務端提供了頁面元件的渲染函式Result.vue,在呼叫函式渲染時我們可以在 initProps 引數中傳遞初始化的資料物件;這些資料可以在建立 vue 例項時會註冊為元件例項的 Props 引數。在頁面元件中我們可以將其定義為 Props。 瞭解 vue 元件 Props。
在服務端路由外掛呼叫vue時:
Result.vue('index', {  title: 'xxx',  keywords: 'xxx',  description: 'xxxx',  say: 'hi!',})
在頁面元件中我們可以直接通過 Props 將服務端直出的資料在 vue 模板中使用。
**特別說明:**在initProps引數中,title,keywords,description還會預設被解析為 web 網頁頭中的 標題,關鍵字,描述填充。

asyncData 靜態方法

asyncData是頁面元件資料獲取的鉤子,只能作用於頁面。其接收物件引數預設是vuex的store和當前router,通過router可以獲取到當前路由的引數等資料,然後呼叫非同步請求獲取 http 型別的資料,然後通過store觸發狀態管理的更新,也可直接改寫操作store.state屬性。框架會合併到store資料上下文state中。
asyncData靈感來自官方vue-ssr 示例和nuxtjs


05

HTML和SEO

框架內建HTMLWebpackPlugin外掛,開發者在頁面元件同級目錄下可以覆蓋預設 html 模板自定義引入第三方資源和指令碼。自定義 html 檔名為頁面下的index.html。

頁面TDK

外掛傳值initProps中預設接收title,keywords,description作為頁面標題,關鍵字,網頁描述填充欄位。
Result.vue('index', { title: 'xxx', keywords: 'xxx', description: 'xxxx' })

模板插值

在 html 模板中,還可以使用模板插值。服務端渲染初始化時傳遞的initProps資料在服務端渲染時會被注入為渲染上下文物件。



06

VUEX

當專案比較複雜時,我們可以在頁面元件入口檔案中匯出 Vuex store 物件。框架會自動從根頁面元件注入 vue 子元件中,通過$store 訪問到例項化後的 store。

框架接收到 Store 物件後,會例項化 vuex。並且初始化到 vue 例項中,通過 vue.use 注入到全域性。對於初始化的 state 資料,如果在 initProps 中也傳入同名的屬性,則 initProps.state 將會覆蓋主入口檔案傳入 store.state 中的屬性值。
Result.vue(ctx, 'vuex', { state: { count: 200 } })
在頁面元件中獲取初始state。
最後展示到頁面上的count初始值為:200


07

巢狀路由(vue-router)

本身專案是沒有引入vue-router的,各個頁面元件之間是完全獨立的兩個專案。 當 vue 頁面元件需要和 vue-router 結合開發單頁面應用時,在入口檔案中我們也可以通過 Router 屬性匯出路由配置。
在App.vue中匯出路由配置
注意:服務端渲染模式下不支援使用 import 動態匯入元件方式進行路由懶載入
  • 服務端路由
    對於服務端我們需要保持客戶端和服務端路由一致,否則會出現子路由頁面重新整理404現象。
  • 頁面路由獲取資料
    在頁面元件中頁面資料獲取方式和普通頁面元件保持一致,我們可以使用服務端渲染 props 直出和 asyncData 鉤子函式兩種方式獲取,具體使用參考資料獲取章節。


08

內建css支援

框架內建了vue-style-loader以及 css 前處理器 loader,支援*.vue單個檔案元件內的 <style>提取為單獨 css 樣式檔案。也支援 CSS Modules。以下示例均開箱即用,無需額外配置。

  • Scoped CSS
  • 前處理器 less/scss
  • CSS Modules
    對於css modules除了支援vue官方style module方式之外,框架內建了基於less,scss前處理器的css module使用。
    如果你的樣式是從 JavaScript 中匯入的,那麼你只需要將把檔案命名為*.module.(less|scss|css)。


樣例:

  • https://github.com/Umajs/umajs-vue-ssr
線上樣例工程中包含了豐富的示例,包括vuex,vue-router,elementUI,Ant-design-vue,以及css-module的使用。

原始碼:

  • https://github.com/dazjean/srejs
  • https://github.com/Umajs/plugin-vue-ssr
  • https://github.com/Umajs/plugin-react-ssr


資源參考:

  • https://github.com/Umajs
  • https://cn.vuejs.org/v2/guide/components-props.html
  • https://ssr.vuejs.org/zh/guide/data.html#資料預取儲存容器-data-store
  • https://zh.nuxtjs.org/docs/2.x/features/data-fetching#async-data
UMajs 是一個簡單易用、擴充套件靈活,基於 TypeScript 的 Node.js Web 框架。從 2018 年立項至今,UMajs 團隊持續的對框架打磨、迭代,在生產環境穩定執行近兩年後,於 2020 年 8 月份開源。
  • 原始碼:https://github.com/Umajs
  • 官網:https://umajs.gitee.io/
歡迎大家start支援和參與貢獻
往期文章推薦:

作者:

張佳佳,ABG資深前端開發工程師,目前專注於UMajs生態的建設和SSR。歡迎新增微信溝通交流:Da_ZJean(群二維碼過期請新增微信拉進交流群)

本文分享自微信公眾號 - 58技術(architects_58)。
如有侵權,請聯絡 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。