Vapperjs - 一個基於Vue 的SSR 框架
如果你正在使用Vue做同構的項目,那麼Nuxt以及Quasar Framework都是不錯的選擇。但是今天我要介紹的是由水滴前端研發的一個基於Vue的SSR框架:
Vapperjs是一個開源項目,Github:
Vapper的特性
我猜大部分同學在看到這篇文章之後的第一個疑問應該是:為什麼不直接使用Nuxt
或者Quasar Framework
等框架,而是又造了一個輪子?接下來我們將嘗試通過介紹Vapper的特性來解答這些問題,來看看Vapper有什麼不同之處。
目標一:盡最大的努力讓SSR應用的開發體驗更接近SPA
如何才能做到這一點呢?我們需要分幾個方面來考慮:
- 一、項目結構:
與其說項目結構,更準確的說法應該是文件的組織方式。我們知道
Nuxt
是基於文件系統的路由,這意味著它與傳統SPA
應用在文件的組織方式上就必然存在差距,你需要按照其規範(或規定的方式)去編寫頁面(或組件)。然而,我們在開發SPA
應用時完全沒有這些限制,因此我們希望有一個框架能夠讓我們不受任何限制的去組織文件,就像普通SPA
應用一樣。要實現這一點其實並不難,因為Vue SSR的官方文檔教給你的就是這種方式,因此
Vapper
就在此基礎上的封裝。 - 二、數據預取:
用過
Nuxt
的同學一定對其提供的asyncData
組件選項很熟悉,你需要在asyncData
函數內做數據預取,但是它有一些限制,例如該組件選項不能用於任何組件,只能在路由組件中使用(或pages
),並且在asyncData
函數內是不能訪問組件實例對象的。數據預取,簡單的理解就是請求數據,我們在開發
SPA
應用時從來沒有因為請求數據而關心過是否只能在路由組件中請求數據,更沒有關心過請求數據時不能訪問組件實例的問題(這裡我們假設是在mounted
或created
鉤子中進行數據預取)。因此我們希望有一個框架能夠讓你免除這些心智負擔,並儘最大努力讓同構應用的數據預取更加接近SPA
應用。Vapper
讓這一切成為了可能,詳情可以閱讀官方文檔,了解在Vapper
中如何進行數據預取: Data prefetch通過在如上兩方面的努力,我們就幾乎做到了讓開發
SSR
應用的體驗更加接近開發SPA
應用。
目標二:只負責必要的webpack配置
很多人力富裕的公司或團隊基本都會開發一個所謂的腳手架工具,但是絕大部分團隊開發的腳手架工具都只是實現了1%功能的Vue CLI3
,實際上在Vue CLI3
現有的架構下,理論上你完全可以實現任何業務特定場景的需求,而不需要自己再編寫一個腳手架。
Vue CLI3
的架構借鑒了Poi , Poi也是一個優秀的webpack
管理工具,一個優秀的項目腳手架。因此我們希望有這樣一個SSR
框架,它本身只負責必要的webpack
配置,即只負責SSR
相關的webpack
配置,其他的配置交給這些優秀的腳手架管理。這麼做的好處就是雙向的,即Vapper
為這些腳手架提供了SSR
能力,同時這些webpack
管理工具的能力也成為了Vapper
的能力,一舉兩得。
Vapper
中有一個Configer的概念,簡單的說就是兩個模塊:
- @vapper/configer-vue-cli
- @vapper/configer-poi
這讓
Vapper
與這些優秀的webpack
管理工具結合成為了可能,而且更重要的是就算你不適用Vue CLI3
或者Poi
,你也可以編寫自己的Configer
從而集成到你自己的腳手架中,文檔可以閱讀這裡: 編寫Configer 。
目標三:路由級別的控制能力
什麼是路由級別的控制能力呢?為了便於理解,我貼一張官網的圖片:

一句話,我們希望訪問不同的路由會根據需要而採用不同的處理方式,例如我們希望當訪問路由/home
時應用服務端渲染( SSR
);但是當訪問路由/foo
時直接返回SPA
資源給用戶;甚至當我們訪問路由/bar
時,我們可以把預渲染好的內容髮送給客戶端。
之所以要這麼做,是因為有的時候,並非所有項目我們都需要進行SSR
,而且我們可以對部分頁面進行預渲染,這些都是提升服務性能的有效途徑。
在Vapper
中你可以輕鬆做到這一點,你可以通過在路由meta
中指定ssr: true/false
來選擇開啟或關閉SSR
,例如:
new VueRouter ({ mode : 'history' , routes : [ { path : '/home' , component : () => import ( './components/Home.vue' ), meta : { // 应用SSR ssr : true } }, { path : '/foo' , component : () => import ( './components/About.vue' ), meta : { // 关闭SSR,当用户访问/foo 时将会得到SPA 资源ssr : false } } ] })
就是這麼簡單直率,同時不得不提的一點是,如果所有路由都沒有應用SSR
,那麼你的項目和SPA
應用沒有任何區別。換句話說,如果你想將現有SPA
項目逐步遷移為SSR
項目,那麼Vapper
非常適合你。
對於預渲染要稍微複雜一點,你需要安裝@vapper/plugin-prerender插件,然後在vapper.config.js
中進行如下配置:
// vapper.config.js module . exports = { plugins : [ [ '@vapper/plugin-prerender' , { // 写下要进行预渲染的路由routes : [ '/foo' ] } ] ] }
這樣在構建階段, vapper
會對/foo
進行預渲染並生成html
文件,當用戶訪問此路由時,會直接將該html
文件發送給客戶端。需要注意的是,只有開啟了SSR
的路由才支持預渲染,當然這是合理的。
目標四:錯誤處理方式
Vapper
讓錯誤的處理方式更為靈活,當錯誤發生時我們有兩種選擇:

除了展示自定義的錯誤頁面之外,還可以選擇回退的SPA
模式。這麼做的好處是顯而易見的。因為有些錯誤可能只發生於服務端,或者有些錯誤是非致命的,對於這樣的錯誤發生時,我們可以選擇回退到SPA
模式,這樣用戶就可以繼續使用我們的應用,這對於一些注重轉化率的場景是至關重要的。
更多內容可以閱讀: Error Handling 。
更多特性
除了以上介紹的幾個核心目標之外, Vapper
還擁有其他出色的特性,例如:
- 開箱即用的micro-caching和Component level cache支持
- Vapper為應用注入的那些有用的組件、屬性和方法
- 自定義Connect/Express/Koa Server
- Vapper的插件架構和插件的編寫
- Vapper現有的內置插件
我們已經在自己的項目中使用了
Vapper
,歡迎Star
、PR
: