圖解基於 Node.js 實現前後端分離

亞里士朱德發表於2016-04-21

首先慶祝 w3ctech長沙站第12期技術分享會 圓滿成功,感謝組織方邀請~

w3c

因為會上出了個意外,ppt圖片全部丟失,只好對著白板跟大家交流了半個多小時。由於我做演講不喜歡寫太多的文字,沒有圖片的情況下講漏了一些內容。這篇文章是我在會上分享內容對照ppt進行地整理。

基本介紹

首先從一個重要的概念“模板”說起。 廣義上來說,web中的模板就是填充資料後可以生成檔案的頁面。 嚴格意義上來說,應該是模板引擎利用特定格式的檔案和所提供的資料編譯生成頁面。模板大致分為前端模板(如ejs)和後端模板(如freemarker)分別在瀏覽器端和伺服器端編譯。

由於當場有一部分同學對node.js並不是很瞭解,這裡補充一下node.js的相關知識。官網上的給他的定義事件驅動、非同步什麼的就不說了。這裡借用樸靈書上的一張圖來解釋一下node.js這個玩意的結構。如果懂java的同學可以將其理解為js版本的jvm。 瀏覽器一般包括渲染器和js指令碼引擎,以chrome瀏覽器為例,用的webkit核心的渲染器,V8的指令碼引擎,而node.js用到了v8引擎。總而言之它就是一個js的執行環境,就好比瀏覽器的F12除錯工具,只不過node.js沒有DOM和BOM。

這張圖描述的是node.js周邊的一些資訊,比如npm這個出色的包管理器和cnode社群以及github,都在一定程度上促進了node.js的繁榮,提供了技術保障。

大公司通常都是技術的風向標,例如google的angular、facebook的react現在都很火。這裡只列了3個大公司當作例子。淘寶的中途島架構就不用說了,國內node.js的先行者樸靈就來自淘寶。去哪兒也出了個應該叫做“QTX”的技術框架。360月影帶領的75團隊出了個基於ES6/ES7的web伺服器框架——thinkjs,當時我們技術總監很看好,但是由於鄙人沒有時間學習ES6再加上外掛不夠豐富,所以還是選用了較為成熟的Express。

言歸正傳,這個表格列出了我所接觸過的3種前後端分離的開發方式。 第一種是最常見的使用java之類的後端語言模板,SEO友好,快取利用率和減輕瀏覽器渲染負擔方面都比較好,最大的問題就是模板檔案的耦合度太高,出了問題誰都不想來解決,前端人員看不到資料,後端人員不懂頁面,模板檔案就像是一個燙手的山芋。 第二種是目前我們專案移動端的實現方案,利用angular這種框架(angular的指令可以看成是前端模板)和nginx這種反向代理伺服器,讓前後端徹底解耦,只通過ajax互動資料。這種方案和前一種的優缺點剛好相反。前端模板的效能始終是個問題,尤其是在移動端,更尤其是在低端的移動裝置上。 最後一種是新專案使用的用node.js做前端伺服器,將前端的職責從瀏覽器劃分到了模板這一層,解決了以上所有的問題,不過確實也有新的問題,這種問題稍後再分析。

當然全棧開發在小型專案中也是非常適合的。對於傳統的jsp/php開發來說,全棧開發的溝通成本更低,開發人員能更容易理解整個功能模組,從而更好的還原產品的設計。尤其現在出現的以js語言為基礎的全棧開發:meteor和MEAN技術,更是使得前後端開發用一種語言直接搞定,再配上Mongodb,資料從瀏覽器到資料庫都無需轉義直接使用,還不用寫sql,開發成本又大大降低。

這次搭建node.js伺服器用到的一些外掛。 鼎鼎大名的express不用多介紹了,輕量級web伺服器框架。 用handlebars模板引擎也屬巧合,因為express4預設就是它,handlebars不愧為“弱邏輯”的模板引擎,主張的是減少模板邏輯,儘量只用變數和分頁,基於它的設計理念,我只擴充了兩個helper。具體文章:https://yalishizhude.github.io/2016/01/22/handlebars/superagent的使用還是因為express4,因為它的測試程式碼用的是supertest,supertest是基於superagent,所以用了superagent來轉發和發起請求。superagent還是太弱了,長連線都無法建立,還是推薦request外掛。 restfuleAPI就沒什麼好介紹了,前端伺服器與瀏覽器,前端伺服器與後端伺服器都是用的這一套規範,基本上就是url指向資源,增刪改查又具體的請求方法表示,狀態碼錶示結果等~ gulp打包工具,webpack研究了很久,發現每增加一個頁面都要修改配置檔案,這個太蛋疼,遂放棄。

開發流程

如果這次分享主要是講怎樣將node.js做為前端伺服器來實現前後端分離的話那也沒什麼好講的,看看淘寶UED的文章就好了。前後端分離其實最大的問題是帶來溝通成本的上升,具體來說就是介面的定義和除錯。在上圖的傳統開發流程中,介面的定義會放在介面伺服器中,然後前後端各自根據介面文件造假資料進行本地除錯,之後進行聯調。這個環節就是前後端開始撕逼的時候了,這個引數不對,那個返回值不對,總之很浪費時間。接下來看這個問題在我們專案中是怎麼解決的~

前後端因為介面撕逼的問題一直存在,作為保守主義的我相信迭代開發,所以第一步做的只是增加了一個mock伺服器。這個伺服器的神奇之處就是根據介面文件自動生成假資料,實現了介面即API,前端同學再也不用把資料寫死進行測試了。沒辦法,誰叫我是前端開發,首先想到自己人,嘿嘿~當然這個只在一定程度上有利於前端開發,後端的介面和文件不一致聯調時也會出現問題。怎麼辦?

偶然在破浪大神的部落格上看到老馬的一篇專門講前後端分離的文章,其中一個重要的概念就是契約測試也叫雙邊測試吧。核心概念就是為了解決遠端聯調的問題。對前後端的引數都進行校驗,要求大家按照介面文件進行開發。受其啟發,加入json-schema規則,實現了對http請求的引數校驗,誰不按規矩來誰改。

這個redmine是我們最早的介面文件管理器,除了記錄和檢視功能再無其他作用。

swagger號稱世界最流行的介面文件伺服器,介面美觀,外掛也還比較多,可以針對後端語言直接生成測試程式碼。不過部署的時候始終沒玩懂,而且yaml格式不如json習慣,放棄了它。

這就是現在我們專案上用的文件伺服器和mock伺服器,基於MEAN技術實現的伺服器,基本功能:

  • 利用mockjs外掛,可以動態生成隨機資料
  • 基於json-schema對介面引數實行校驗和介面測試,並儲存測試狀態和介面響應時間。
  • 簡單的json編輯器
  • 帶有登陸校驗功能,可登陸後進行介面除錯
  • mock伺服器按照api伺服器來響應請求,介面更新時自動更新

一些問題

node.js是前端工程師的翅膀,而插上翅膀是變成天使還是變成惡魔?這個要看能不能解決的使用它時帶來的問題了。

  • 首先前端的工作量毫無疑問地會增加,但溝通成本會降低。
  • node.js單執行緒的伺服器穩定性確實不夠好,不過程式碼的健壯性和完善的日誌可以有效的規避。
  • 回撥。這個問題解決方法就太多了,node.js的q/async模組以及ES6/ES7。
  • node.js除錯。雖然我一直排斥IDE,但不得不承認webstorm在除錯上確實很方便。我用的node-inspector也還湊合,介面類似chrome開發者工具,看上去挺熟悉的。

如果對於後端程式設計師,更加應該擁簇node.js了。介面整合的工作交給了前端伺服器進行處理,同時和前端耦合度大大降低,工作量和工作效率都減少了。

心得體會有兩點

  • node.js的使用雖然有一定的學習成本,但對於前端開發人員還是很友好的。而且前端使用node.js的話,無論是技術含量還是工作量都會有所提升,從而提升了崗位的重要性。當前端開發人員能創造更多價值的時候才有資格要求更高的薪水~
  • 工作中建議少提建議多給可行性方案,同時進行技術預研而不是寫個簡單的helloworld。

總結

可能有人說你介紹的這一套東西這麼複雜,用起來太麻煩了,還不如面對面溝通。 對於這樣的質疑我只能用騰訊高階UI工程師餘果在《web全棧工程師的自我修養》中講到的一個例子。有一次他電面一家小公司的前端負責人問他怎麼管理程式碼時,對方說直接用ftp上傳,同時抱怨手下人老是更新錯程式碼,又問他為什麼不用svn或git,他說還不如手動更新方便。 這個故事的道理就是我面對質疑的回答~

ppt下載地址

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

圖解基於 Node.js 實現前後端分離 圖解基於 Node.js 實現前後端分離

相關文章