一、背景
在今年年初我開始接觸vue的時候,就發現在vue官方文件中“服務端渲染”的一節中提到了Nuxt.js框架,SSR這種方式對於首屏的載入時間優化顯而易見,同時還可以方便的進行SEO。美團點評的點餐業務中,資料平臺因為其資料量大的特點,首頁載入時間很長,非常適合進行SSR改造;於是,我在非工作時間對nuxt.js框架進行了嘗試,吃了一波螃蟹。本文對nuxt.js框架應用於生產環境進行了系統的論述,同時對所踩的坑也進行了一定的介紹。
官方對nuxt.js的介紹如下:
Properly configuring all the discussed aspects of a production-ready server-rendered app can be a daunting task. Luckily, there is an excellent community project that aims to make all of this easier: Nuxt.js. Nuxt.js is a higher-level framework built on top of the Vue ecosystem which provides an extremely streamlined development experience for writing universal Vue applications. Better yet, you can even use it as a static site generator (with pages authored as single-file Vue components)! We highly recommend giving it a try.
可以看出,vue官方對於nuxt.js的態度非常積極,還是值得大家嘗試的,目前最新版本:1.0.0-rc2;1.0正式版即將釋出,撒花!
因本文作者水平所限,如有錯誤,歡迎拍磚。
二、nuxt.js 簡單介紹
1、nuxt.js的原理圖:
具體的原理介紹官網有詳細的解釋,歡迎讀者移步官網,這裡不再複述。
2、nuxt.js的優勢
三、技術棧選型
1、nuxt.js:0.10.6
2、axios:0.16.2 → 選擇axios的原因很簡單,它是vue官方推薦的包,並且axios可以執行於瀏覽器端和伺服器端,減少了前端工程師的學習成本。
3、elementUI:1.3.7 → elementUI是基於vue的很全面的ui元件庫,對於一個自己的驗證專案很合適,可以快速開發,快速上線。
四、實施方案
工程的目錄結構如下:
1、外掛安裝
你可以配置需要在“根vue.js應用”例項化之前需要執行的js外掛,當然可以是你自己寫的或第三方模組。
注意:在任何vue元件的生命週期內,只有beforeCreate和created這兩個鉤子會在瀏覽器端和服務端均被呼叫;其他的鉤子都只會在瀏覽器端呼叫。
1)對於axios這種ajax請求外掛,無疑會使用在頁面的方方面面中,那麼如果在每個頁面中使用import方式進行引入,會導致在打包的時候打包多次。而實際上我們只需要打包一次,可以通過在nuxt.config.js裡面的build.vendor來解決。
當然,如果你需要區分測試環境和線上環境的介面地址,就需要在plugins檔案中對axios進行編寫,如圖:
2)使用vue外掛 - elementUI
普通的npm包的引入方式如上面的axios所述,那麼vue外掛我們該怎麼處理呢?
- 首先我們需要在plugins資料夾中新增外掛檔案,element-ui.js
- 在nuxt.config.js中配置plugins欄位
- 由於elementUI是第三方庫,我們需要把它打包到庫檔案裡面以獲得更好的快取效果。在nuxt.config.js中配置element-ui即可。
3)同時nuxt還支援區分只在瀏覽器中執行和只在服務端執行的外掛。
- 只在瀏覽器執行:配置nuxt.config.js中plugins欄位,將引入的外掛屬性設定為ssr: false
- 只在服務端執行:直接在webpack打包server.bundle.js檔案中,將process.SERVER_BUILD設定為true即可
2、layout佈局
nuxt.js實現了一個新的概念,layout佈局,我們可以通過layout佈局方便的實現頁面的多個佈局之間方便的切換。本專案中實現了三種常用的佈局,即:1)兩欄佈局,左欄固定,右欄動態寬度;2、錯誤頁提示,頁面中間一個提示框的佈局方案;3、純白頁面佈局。
以兩欄佈局舉例:
- 首先,在layout → default.vue中編寫預設佈局
layout與頁面的具體內容的插口即:nuxt標籤 - 具體開發的頁面中,如果使用預設佈局,則不需指定頁面的佈局,nuxt框架會自動對沒有指定佈局的頁面和default佈局進行關聯。如果需要指定佈局,則在layout欄位中對佈局進行指定。如圖在login頁面中對full佈局進行了指定。
注:個人開發感受:layout佈局對於頁面型別多變的工程很有好處,我們可以減少冗餘程式碼,並且方便開發人員在多個佈局中簡單切換。nuxt框架將頁面分層劃分為3層:1、佈局;2、頁面;3、元件
這麼劃分邏輯上更清楚,也更貼近元件化頁面開發的思想。
PS:個人在非vue專案中也自行實現了一個簡單的layout佈局,使用slot插口即可實現。
layout檔案提供slot插口
在開發頁面中將layout檔案以元件的方式引入即可。
3、server端api編寫
nuxt的server端使用的是express,故server端api直接編寫express router即可。server端目錄組織如圖:
server/index.js 檔案是express的啟動檔案,plugins和middleware檔案是axios的配置,api資料夾內即api介面。
server/index.js檔案裡面對api引用如下:
我們先看看axios的配置,通過對process.env的匹配來區分線上與測試環境,同時在middleware檔案中對介面進行鑑權。
之後在api/index.js檔案中對各介面進行引用和聚合
在所有介面檔案中,以announcement.js舉例:
可以看到為了實現簡便和避免過度設計,api介面沒有對資料進行重新封裝,直接進行了透傳處理。
4、頁面路由
nuxt框架的頁面路由使用了vue-router,但是我們不需要對頁面的路由進行過多的操心,因為我們只要按照nuxt規範的頁面檔案目錄結構進行設計,就可以自動生成vue-router檔案。或者說我們存放頁面的目錄結構會直接影響最終生成的路由配置。
本專案的頁面目錄結構如圖所示:
而生成的router檔案為:
可以看出生成的路由與pages資料夾目錄結構是一一對應的。
注意:其中帶引數的動態路由,需要建立對應的下劃線作為字首的vue檔案或目錄。例如圖中bidDetail/_id.vue檔案,最終生成的路由即為:path: "/bidDetail/:id?"。
五、總結
從頭搭建一個服務端渲染的框架其實是相當複雜的,不過有了nuxt.js後,我們可以很輕易的搭建出一個可擴充套件可定製的SSR框架,這大大的減少了我們搭建框架的時間成本。因為nuxt的官方文件寫的足夠詳細,我沒有對安裝這類常規項進行描述,直接從外掛安裝、新概念 - layout佈局、server端api、pages的組織入手,介紹了我在專案實戰中使用nuxt框架的一些關鍵路徑。目前專案上線在aws跑了半個多月,總體穩定,說明雖然nuxt不是1.0版本,但是也足夠用於生產實踐了。(考慮到github上說。nuxt的1.0版本即將到來,我們有理由期待vue的SSR前景)
由於本文作者水平與篇幅所限,不能對專案中的所有細節盡述,對nuxt感興趣的讀者可以郵件聯絡:wangxinghang@meituan.com,感謝~