不僅僅是複製粘貼 - 聊聊前端腳手架

閱讀原文

許多團隊在制定前端工程方案時會加入腳手架模塊。雖然不同的團隊對工程化的理解和實施有所差異,但是對於腳手架的定位基本是一致的:創建項目初始文件。這是一條看起來十分簡單地準則,但是對於這條準則應該如何理解,如何實施卻並不是一件很簡單地事情。

在探索這條準則的深度之前,我們不妨看看類似的一些成熟方案,比如Eclipse。這個大名鼎鼎的IDE軟體被很多Java和Android開發者使用。通過Eclipse創建一個新項目時,它提供了豐富的配置項,這些配置項可以歸納簡化為以下流程:選擇項目類型 -> 選擇項目目錄 -> 配置項目細節 -> 最終確認 -> 完成。這是腳手架最基本也是必須具備的流程。從這個流程中可以總結出腳手架的本質:方案的封裝

由此,我們明確了腳手架的定義:腳手架作用是創建項目的初始文件,本質是方案的封裝

當然,腳手架創建項目流程之中還有很多細節,並且前端項目的多樣性和複雜性更加為腳手架流程的實現增加了難度。這篇文章簡單闡述一下筆者的一些淺見,希望能夠給大家一些啟發。

1. 腳手架在前端工程中的角色

1.1 「用完即棄」的腳手架

之前寫過一篇淺析前端工程化,簡單介紹了前端工作流模型,簡化之後可以用下圖概括:

腳手架在前端工作流中負責項目起始階段創建初始文件。與其他功能模塊不同的是,腳手架是一個完全「啟下」的模塊,它沒有任何前置依賴。創建完成項目初始文件之後,腳手架就再無用武之地了。

「用完即棄」的工作模式令腳手架的實現由很大的躍遷性。你可以用最簡單的複製粘貼就能完成腳手架的工作,而一個完備、成熟的腳手架即使提供了非常豐富的交互配置,最終目的也「只」是創建了一堆初始的項目文件。既然結果一樣,那為什麼還要花費時間和人力成品去開發複雜的腳手架方案呢?

躍遷是量子力學術語,意思是狀態發生跳躍式變化的過程。之所以將這個詞用在這裡是因為高度完備的腳手架相比較低級形態的腳手架而言,能夠帶來質的飛躍。

這是一個非常現實的問題,互聯網產品迭代的快速節奏下,開發團隊最注重的就是投入產出比,而腳手架的投入產出比「看上去」是最低的。環顧目前前端的工具生態,最多的是構建工具,當然我們不可否定構建確實是最複雜的功能。而腳手架工具是最少的,前端社區對腳手架的討論也非常稀少。你可能聽說過大名鼎鼎的yeoman,但是很難再想出第二個腳手架工具了。

單獨來看,腳手架可能並不具備很高的「性價比」,但如果你的團隊有一套完整的前端工程體系,腳手架的作用就會被放大。前端工程體系的功能涵蓋範圍廣,封裝的方案類型多,對應的配置項也非常複雜。而且,大多數前端工程體系的開發者並不是一線的業務開發者。對於業務開發者來說,這套工程體系就是一個黑盒,他們不需要了解其中的複雜原理,只需要知道如何配置即可。所以業務開發者的需求就是快速開發快速配置,並且生成的配置項跟項目要對應,既要滿足項目的功能需求,又不能有「混淆視聽」的冗餘功能。

前端工程體系不是Vue、React這種開發框架,工程體系只是一種「服務」,是輔助性質的。學習曲線應該平緩,即使文檔再清晰易懂,也不應該要求業務開發者去花時間學習各種細節。這就是對腳手架要解決的切實問題,簡單說就是:

  • 快速生成配置;
  • 降低框架學習成本。

隨著前端工程體系越來越複雜,腳手架的角色會越來越重要。

1.2 腳手架需要具備的要素

1.2.1 執行環境僅限本地

在討論實現一個腳手架要考慮哪些要素之前,我們不妨先看看腳手架的執行環境。回顧前文提到的簡易前端工作流,最簡單的情形是:框架提供一套完整的本地工具鏈,腳手架、開發、開發伺服器、構建和部署測試都是在本地環境執行,如下圖:

進一步的團隊會搭建CI(持續集成)平台,將構建和部署功能遷移至雲端,這樣做便於工作流程式控制制和代碼統一管理。如下圖:

不論哪種工作流,腳手架始終是在本地執行。

1.2.2 模式不固定

前端腳手架之所以沒有固定的模式,是由於不同的公司對於前端工程師的定位不固定。比如有些公司的前端仍然是「切圖仔」;有些公司的前端負責瀏覽器端的所有邏輯開發但是html模板層仍然由服務端工程師維護;還有些比較前沿的團隊提倡「大前端」,負責瀏覽器層與中間層(主要承載html的渲染功能)。前端工程師定位不固定就造成了前端項目模式的不固定,腳手架自然也具備了多樣性。

不論是哪種工作模式,一個優秀的前端腳手架都應該具備以下幾點要素:

  1. 豐富但不繁瑣的配置項;
  2. 與其他功能模塊聯動,生成對應的基本配置項;
  3. 自動安裝依賴;
  4. 底層的高度可擴展性;
  5. 支持多種運行環境,比如命令行和Node.js API。

如何理解「豐富但不繁瑣的配置項」呢?舉個例子,假設構建功能支持自動生成css sprites,配置項有兩個:

  1. 是否啟用css sprites;
  2. 指定散列icon目錄。

腳手架在實現針對css sprites的配置項時是不是應該將這兩個配置都開放給用戶配置呢?顯然是不需要的,腳手架只要開放是否啟用css sprites的配置項即可,因為這是影響這項功能最重要的一點,散列icon的目錄即使用戶不配置,使用默認的方案也不會造成任何不便。

另外,在實現腳手架時不應該只看到當前的需求,還應該考慮後續需求的變更和新增。所以一個優秀的腳手架應該具備高度的可擴展性,便於定製不同類型的方案。從這個角度來說,目前yeoman是做得最好的。

2. 開源前端腳手架方案剖析

明確了腳手架的基本工作模式,我們不妨看看目前業內有哪些可以借鑒的案例。我們在這裡介紹三種形態的腳手架:

  • sails是一個Node.js fullstack框架,其使用的sails generate腳手架主要是針對服務端代碼設計;
  • 優酷PHP中間層框架是筆者前團隊使用的開發框架,目前並未開源。其使用的腳手架相對sails來說比較簡單,只能創建一個完整的webapp,包括Controller層和瀏覽器層代碼;
  • yeoman是廣為人知的開源腳手架工具,它本身不提供任何直接創建文件的功能,而是一個腳手架底層框架,你可以定製自己的腳手架實現。

其中兩個是開源項目,大家可以在Github上獲取對應的源碼。

2.1 sails - Node.js fullstack框架

sails是一個Node.js全棧框架,服務端使用MVC架構。sails generate是sails的腳手架模塊,默認可以闖將以下幾種模塊的初始代碼:

  • app - 創建一個新sails項目;
  • api - 創建一對model和controller;
  • model - 創建一個model;
  • controller - 創建一個controller;
  • adapter - 創建一個adapter;
  • generator - 創建一個腳手架模板。

sails框架中的Adapter可以簡單理解為操作model的API映射適配器。

大家注意最後一種類型:generator。sails在默認的腳手架基礎上,開放了自定義腳手架模板的API。

sails默認的腳手架大都是針對服務端代碼的,如果不藉助其他腳手架模板,瀏覽器端的代碼(JavaScript/CSS/Views)只能手動添加。

2.2 優酷 - PHP中間層框架

優酷的PHP中間層框架並未開源,所以就粗略的介紹一下吧。

中間層框架不涉及Model層,不涉及資料庫操作,只包括Controller和View層。這個框架的理念是:任何一個模塊都被視為一個webapp,比如登錄/註冊模塊Passport、訂閱模塊Subscribe等,每個webapp都是一個SPA。腳手架只能創建一種文件類型:一個完整的webapp。其中包括Controller文件、Resource文件(瀏覽器層)和路由配置文件。

由於每個模塊webapp都是一個SPA,包含一個Controller文件,一個view入口文件、一個入口js文件和一個css文件,所以腳手架創建的初始文件就已經夠用了,開發者只需要手動添加子模塊文件即可。同時,技術棧統一,build功能封裝完備,不需要額外配置。這種形態的腳手架基本滿足了優酷PHP中間層框架的需求。

2.3 yeoman - 可能是最好的開源腳手架框架

提起腳手架這三個字就不得不提到yeoman這名老將。Yeoman在2012年Google I/O上首次發布,至今已經5年的光景了。對於前端技術圈子來說,5年的時間可以讓絕大部分的技術遭到淘汰,而yeoman堅持到了今天,且扔未現衰退之勢。我們可以短暫回顧一下5年前的前端技術,你可能會想到Knockout和Backbone,也可能會想到現在YUI 3,甚至可能會想起被ExtJS所支配的恐怖。然後再看看這些在當時熱火朝天的技術目前的市場狀態,是否都已是昨日黃花垂垂老矣?而yeoman之所以能「活」這麼久,跟它的定位是息息相關的。

yeoman的slogan是「THE WEB』S SCAFFOLDING TOOL FOR MODERN WEBAPPS」-腳手架工具,但我個人認為稱之為腳手架框架更為合適。yeoman不能直接創建項目文件,它提供了一套完整的開發腳手架API,你可以通過這些API定製符合自己業務需求的任意的腳手架方案。換句話說,yeoman不封裝任何方案,它是完全開放、高度可擴展的。

yeoman的API具備了前文所列出的腳手架需要具備的所有要素,如果你需要開發一個屬於自己的腳手架,yeoman是最好的選擇。後續的博文會詳細介紹如何使用yeoman提供的Node.js API將其集成到工程化框架中。

3. 總結

雖然前端腳手架沒有固定形態,但是有必須具備的要素。從功能實現的角度,要考慮與業務的高度匹配;從底層平台的角度,要具備高度的可擴展性和執行環境多樣性支持。

這可能是目前針對前端腳手架理念說的廢話最多的一篇文章了,哈哈。所述內容都是筆者的一些淺薄的心得,希望能夠給大家一些啟發。


推薦閱讀:

HTML里為什麼一些input里要設置value為空?
大公司里怎樣開發和部署前端代碼?
前端構建系統 Gulp 的使用與常用插件推薦 - 上篇
躺下來聊聊前端自動化—node.js、npm、webpack、gulp這些鬼
Gulp資料大全:入門、插件、腳手架、包清單

TAG:前端开发 | 前端框架 | 前端工程化 |