除了SSR,就沒有別的辦法了嗎?

除了SSR,就沒有別的辦法了嗎?

本文首發於我的部落格:

SSR 出啥事了

放心,SSR 沒出事。

寫這篇部落格並不是想說SSR 有什麼不好,而是因為一些別的原因。

想像一個這樣的場景

作為有追求的開發者,我們都希望自己能夠負責一些比較有技術難度的項目。但作為公司業務來說,總會有一些比較簡單的需求,需要做幾個靜態頁,比如產品官網、活動頁之類的。這些需求雖然沒什麼挑戰性,但總得有人來做。

沒有什麼是jQuery 一把梭搞不定的

一般接到這類“簡單”的需求,相信絕大部分人的第一反應肯定是jQuery,儘管它早已落入前端鄙視鏈的最底層,但依然魅力不減,寶刀未老。配合BootStrap 又是一把梭,分分鐘搞定。

時至今日,這套方案依然可行,很好的滿足了業務的需求,對開發者的技術要求也不高,可以說是非常穩了。

那不就行了,你還擔心啥?

教練,我想打籃球

這是一個屬於MVVM 的時代,即便是剛入行的新人也都知道:jQuery 不是終點。

Angular、React、Vue,不管誰是你的本命,一旦入坑,就再也回不去了。即便不為框架故,ES 2015+ 了解一下? LESS、SCSS 了解一下? Pug、EJS 了解一下?用了這些那肯定逃不開Babel、Gulp、Webpack 了吧?

See?不是jQuery 不行了,而是行業的發展,讓開發者更傾向於(至少已經習慣於)用MVVM 來開發。

老生常談SEO

MVVM 的開發體驗是不錯,極大的解放了前端開發者的生產力。但和MVVM 經常一起出現的還有另一個讓人又愛又恨的東西,叫SPA。

SPA 的體驗非常好,頁面切換非常自然。但SPA 最大的問題,就是缺少對SEO 的支持。

為了解決這個問題,主流MVVM 技術棧都提供了對應的SSR 的方案。

SSR 從根本上解決了SEO 的問題,但是實踐起來比較麻煩。一方面上手難度較高:必須使用Node.js、業務代碼要進行同構化改造、Webpack 需要多一套配置、第三方庫需要審查是否支持SSR;另一方面SSR 使得前端的工作需要在瀏覽器和服務器之間來回切換,相比單純的客戶端開發,或是服務端開發,工作內容要更雜。

所以儘管SSR 很強大,但殺雞焉用牛刀。

回到未來

SSR 其實並不是什麼新鮮玩意兒,早在SPA 佔領世界之前,動態頁面本就是由服務端輸出的,前端不過是後端代碼中的一個視圖而已。

我們現在所談的SSR 方案,主要得歸功於Node.js。作為一個運行環境,它使得JS 成為一門全端語言,前端現在所有的繁榮昌盛和麻煩事兒,都源自Node.js 的誕生。

相比於傳統的後端渲染方案,SSR 最大的好處,是兼顧了前端的組件化,和後端輸出的效率。順帶地,由於前後端使用了同一門語言,大量代碼得以復用。

儘管前端現在開發手段花里胡哨,但網頁最終的樣子始終沒變。

因此總的來說,我們的訴求就是:開發階段用MVVM,構建階段利用工俱生成靜態頁面。

“預渲染”了解一下

顯然,我肯定不是第一個提出這個訴求的人,在SSR 方案出來沒多久,就有人開始研究另一種方案—— 預渲染。

大家都覺得,這事兒不一定非得放到服務器去做,Node.js 只是一個運行環境,不用非把它當做服務器來看。如果能在構建階段直接把渲染好的HTML 打出來,問題不就解決了。

於是有人開發出來這樣一個Webpack插件—— PrerenderSPAPlugin

這是一個很厲害的插件,不挑技術棧,無論你是Angular、React、Vue 中誰的粉,只需要簡單設定一下路由,就可以在構建階段直接輸出渲染好的靜態頁面。背後的原理主要是利用Puppeteer加載頁面,並把加載完成後的內容保存下來。

PrerenderSPAPlugin 的好處是改造成本低,如果你有一個現有的系統,需要進行預渲染改造,那麼你只需要調整一下Webpack 的配置即可,業務代碼不用動。

但這個方案只能處理靜態的路由,對於動態路由,這個插件暫時還沒有很好的辦法來解決。

了不起的蓋茨比

開發者大多有自己的部落格,部落格是一種典型的靜態站點,過去有WordPress、JekyII、Hexo 等大名鼎鼎的CMS,都能生成靜態站點。但這些工具目的性都太強,明白兒地告訴你:我就是個部落格。

Gatsby是最近流行起來的一種新型方案, 項目始於2015年,原本只是個副業,開發了一年之後,發現反響不錯,於是創始人開始全職投入Gatsby的開發工作

區別於其它方案,Gatsby 並沒有死盯著CMS 這一個領域,它定位於一種使用React 技術棧開發站點的方式。不光可以用於開發靜態站點,動態站點也完全不在話下。

Gatsby 的頁面就是React 組件,你之前積累的所有React 知識到這裡都可以繼續用,可定制性非常高。

Gatsby 不光支持Markdown 轉HTML 的方式來生成內容,同時還支持從WordPress 等主流CMS 導入數據,或通過外部API 獲取數據來動態生成頁面,方便遷移。

Gatsby 支持自定義路由,靜態動態均可,沒有任何固定的路由套路。

Gatsby 支持部署到Github Page、Now.sh、Surge.sh 等各大主流託管平台。如果你有自己的服務器,你當然也可以自由發揮。

事實上,這篇部落格發布之時,我剛剛把整個部落格用Gatsby 徹底改造了一遍,大家可以感受一下。

想得遠一點

既然Gatsby 這麼強大,那麼我們可不可以用Gastby 來替代SSR 呢?在一定條件下是可以的,但目前有幾個問題還沒能得到很好的處理:

1)動態路由(/user/:id)

對於部落格這種內容已經確定的,可以在構建期就確定有哪些路由,但如果需要通過外部API 來獲取,就需要API 支持GraphQL,否則目前還無法實現。

當然這種情況我們可以換種思路來考慮,使用固定的子路由,通過改變查詢參數,在頁面載入之後再動態獲取內容。這種方法雖然URL 看上去不那麼完美,但解決問題還是可以的。

2)React-Router

一般我們在使用React時都會配合React-Router來管理路由,然而Gatsby並非使用React-Router,它的路由有兩種,一個是src/pages目錄下按照目錄和文件的名稱來定義路由,另一個是通過onCreateNode生命週期手動創建slug來擴展路由。 React 的SSR 框架Next.js 也是採用的類似的方式。這點在遷移老系統時需要重新設計一下。

別急

儘管還有一些問題,但Gatsby 可以說是目前創建靜態站點最完善的方案,既滿足了一個靜態網站所需要的一切,又提供給了開發者非常現代化的開發方式。

項目現在更新很頻繁,包括核心庫在內,每天都有大量的commit。我這次改造大概花了一周時間,期間執行過幾次yarn outdated ,每次都有一堆的可更新項目,全都是gatsby-開頭。

頻繁更新的背後,是一整個團隊不懈的努力。截至發文當時,Gatsby最新版本是2.0.117

小結

總的看來,Gatsby 雖然需要投入一些額外的學習成本,但回報率還是比較高的。

題外話:簡單談一談Imgcook

前陣子阿里爸爸放又出來一個大殺器—— Imgcook ,可以把設計稿一鍵生成可讀性很高的代碼,讓一批前端從業者背後又一涼。

為什麼是“又”?

一方面,人們研究設計稿自動轉HTML 的技術也不是一兩天了。前有Pixel2Code一文驚天下,後有微軟Airbnb等大廠發力相關技術。另一方面,阿里爸爸在過去一年先後推出過好多這一類自動化的項目: 鹿班飛冰Fusion Design

其實這沒什麼新鮮,Word、Photoshop、Sketch 導出成HTML 早就已經是存在了很久的功能了。

每次AI 出點什麼新聞,都會讓一批人背後一涼,擔心什麼時候自己就失業了。但在我看來,AI 再厲害不過是個熟練工。如果一件事情只要重複次數多了誰都能來,那它就有可能被AI 做到,否則,那就不用擔心。不管是設計,還是開發,都屬於創造型工作,從創意到實現的過程或許能被AI 代替,但形成創意的過程,再強大的電腦也算不過來。

What do you think?

Written by marketer

WordPress做了哪些牛逼的網站?

Gatsby精粹,面向未來的blog