在前端項目的規模和複雜性不斷提高的狀況下,各種構建思想和相應工具層出不窮。本文竭己所能對比了當下13個構建工具,包括Browserify
、Webpack
、Rollup
、Grunt
、Gulp
和Yeoman
6個廣爲流行的工具,FIS
、Athena
、WeFlow
和Cooking
等4個國產工具,以及三大框架:React
,Vue
和Angular
的官方腳手架。但願能在項目初期的構建工具選型上爲你們提供些參考。css
構建工具能夠分爲三類:模塊化打包類、任務流構建類和集合型工具類(腳手架)。其中最爲突出的,當屬用於模塊化打包的Webpack
和用於任務流構建的Gulp
。下面是截至2018年11月28日某時某刻,GitHub
上各個工具的Star
數目(據說Star
數目能夠造假?好生無聊的傢伙們!)。前端
前端的構建通常包括JS轉碼(使用Babel
轉ES6
或TypeScript
自轉等)、CSS轉碼(Less
或Sass
轉Css
)、代碼或資源的合併與壓縮,基礎檢查和各種測試等等。這些雖與本文關係密切,但都不在討論的範圍以內。緣由有二:一是實現這些功能的都是某些插件,不是工具自己,各種構建工具都是直接或間接(調用以本身的模式封裝後的插件)使用它們的;二是本文介紹的是,構建方向上的類別和各種別裏不一樣工具間的差別,與具體的操做無關。vue
如今的前端項目基本是模塊化的,緣由就不在這多說。而模塊化意味着分散,沒法直接用於呈現,所以須要進行相應的打包造成一個總體。有些執行環境(Node
)能自動打包各個模塊,而有些(瀏覽器)則由於技術或其它考慮須要自行操做。模塊化打包工具就是爲模塊化項目在瀏覽器上的優化呈現而服務的。react
模塊化打包的核心是:找出依賴,打包成體。各種工具的基本運行思路即是根據已有配置,從某個文件開始,遞歸的找出全部與其相關的依賴模塊,打包成某種類型的可直接在瀏覽器中運行的一個或多個新文件。這之中還能夠優化輸出,以實現代碼分離、異步加載和長效緩存等高級功能。webpack
正如其官網介紹的,Browserify
會遞歸的分析,項目中全部使用require
引入的JS模塊(包括Node
內置模塊)並打包,使得Node
類項目能在瀏覽器上運行。不過對於與項目有關的其它資源,好比Css
和圖片等,依然須要手動管理。雖然網上已有人編寫了支持此些功能的插件,但這不只違背了設計初衷,也使配置變得雜亂。並且對於要求愈來愈高的單頁面應用來講,它能提供的助力着實已顯疲憊。程序員
穩定版已到v4.26.0
,本文以此版本爲據。另附加官方的對比文檔。web
Webpack
的設計思想新穎實用,社區活躍,功能強大全面,已是針對前端各種資源的、目前最優秀的模塊化管理和打包工具。它入門簡單,基本的經常使用功能能很快上手,並用於實際開發。但精通不易,畢竟打包已經是web
開發中最重要的挑戰之一,必然要耗費些許精力。學習尚且不易,介紹就更爲困難,得要有一本書的厚度。所幸此節不是詳細介紹,只是亮點闡述,善哉善哉。npm
掌握了構建的基本思路,任意工具的入門都是較爲簡單的(讀者批:廢話)。之因此強調Webpack
入門簡單,是爲了減輕有意者學習以前的顧慮。一方面是它剛被推出時,因爲自身的概念新穎並且文檔不全面,使開發者處於懵懵懂懂的狀態,總感受離真諦還差些距離。另外一方面是它的體系着實龐大,仔細想一想都難免膽怯。筆者初次接觸時即是這些個感覺。
但如今不同。吃土的日子已經遠去,啃草的夢想還會遠嗎?你們準備好鐮刀!
Webpack
第四版在入門上的方便性體如今三方面。一是基礎功能高度集成和約定優於配置思想:安裝好Webpack
及其CLI
後即可直接打包JS
和JSON
文件,與Browserify
同樣簡單。二是官方文檔詳細(並且有基本同步的中文版),不管是概念的解析、實際運用的示例仍是接口的展現都十分完備。三是如今使用和介紹Webpack
的人已經不少了,所以網上的各路資料和相應問題的解決方案都十分豐富。你還在猶豫?
如從官網上截取的圖片所示,在Webapck
眼中一切文件(.js
、.css
、.jpg
、.woff
、.csv
和.ts
等除了某些用於下載的靜態大文件外)都是模塊,都能經過與JS
類似的方式被打包,並安置於合適瀏覽器渲染的位置。真是十分優秀的立足點。以此思想即可囊括前端會使用到的幾乎全部資源,能夠十分方便的統一管理和安置,更爲便捷和高效。
並且此思想就是爲單頁面應用而生的。在Webpack
的另外一層意境中,一個asset
(各種資源)是一個模塊,一個component
是一個模塊,一個module
也是一個模塊。而單頁面應用的特色,不就是應用的更新不是整個頁面的更新,而是某個module
或component
或asset
的更新嗎?十分的契合。
有人說Webpack
的缺點在服務端渲染(或說多頁面應用)上。喂喂,一來別人的目標本就不在此,二是多頁面應用也不須要如此複雜的支持體系。
單頁面應用或說須要構建才能展現的應用,相比多頁面應用,從每次修改到從新呈現要多經歷一個構建的階段。實際操做中,若是項目龐大而構建性能不夠優化,一個小小的修改(打印某值)都會消耗5秒以上的時間,對開發者來講真是個地獄!而優化的方法不外乎兩點,一是開發者優化項目的構建思路,二是構建工具優化自身的構建性能。
Webpack
擁有較理想的構建性能。在開發階段,當開啓了Webpack
的模塊熱替換以後(使用webpack-dev-server
會自動開啓),一旦檢測到文件被修改,會在應用程序運行過程當中經過冒泡捕獲的方式最小化替換、添加或刪除模塊,而無需從新加載整個頁面。相似Dom
渲染中的迴流:若是子元素髮生的大小變化,會影響兄弟元素但不影響父元素,那麼父元素及其它是無需從新繪製的。並且即使徹底從新構建,也會保留先前的應用程序狀態,減小等待時間。
活躍的社區能夠提高系統的豐富度,下降學習與使用的成本。
Webapck
社區十分活躍,應用於各類需求的插件都被一一封裝而可直接使用(官方也統一展現和說明了一些經常使用的優秀的Loader
和Plugin
)。不僅僅是其它工具的高度協調,開發中的各個階段:搭建本地服務器、集成測試等,以及與任務流工具(Gulp
、Grunt
)的集成等等方面的解決或最優方案,都是豐富和全面的。基本上能夠想到的需求,在這個社區中,都能直接借鑑他人已有的成果。
Rollup
定位爲一個JS
模塊打包器(明指JS
),主要用來構建JS
庫,也可服務於一些無需代碼拆分和動態導入的小型應用程序。能在Webpack
已穩居打包之首的狀況下殺出一條血路,獲得Vue
、D3
、Three
和React
等著名庫的青睞,想必其着手點和性能有過人之處。
Rollup
自己結構簡單,須要的配置項也很少,再加文檔全面,因此很容易上手並所有掌握。它使用ES6
自己的Module
語法做爲本身的標準,而不是諸如CommonJS
和AMD
等之前的解決方案。這意味着按照Module
標準編成的代碼,不只如今能夠藉助Rollup
打包運行,將來更能在實現此標準的瀏覽器上直接運行。
經過Module
的特性,Rollup
開創了Tree-shaking
功能——清除沒有在項目中使用到的代碼。它基於顯式的import
和export
語句的方式,經過靜態分析,排除了任何未在實際中使用的代碼,能極大的減小構建於已有模塊的項目體積。再加上其構建基本不添加自身的控制代碼,使打包後的文件真正的達到純淨二字。想一想還有點癢癢,我撓撓襠部。
Rollup
和Webpack
因其定位和專一點是能夠共同存在並相互支持的。
正如Rollup
官網所說的,Rollup
更適合構建獨立的JS
庫,而Webpack
爲資源豐富的應用程序。雖然Webpack
也增長了本身的Tree-shaking
功能,但在編譯後的輸出代碼中,簡單地運行自動minifier
檢測未使用的變量,獲得的結果是不如原生的靜態分析。更況且Webpack
生成的代碼必定是通過本身包裝後的代碼——將每一個模塊封裝在一個函數中,再置於一個包中,經過瀏覽器能使用的require
方式逐一執行這些模塊。
基於任務的構建行爲,是不在意操做對象是否爲模塊化的。
這類工具的目標是經過配置來解放平常須要重複的工做——轉化、合併壓縮和單元測試等等。有人說:這些操做Webpack
和Rollup
不是也能作?是的,基本能作。實際上,在用模塊化構建工具的開發中,不多會用到任務流構建工具。但這毫不是說任務流工具會被取代,也不會被取代,至少多頁面應用須要。再說任務流工具是十分純粹的自動化行爲,與模塊化打包工具立足點就不同,何談取代一說。
Grunt
雖是老牌構建工具,但依然被許多知名項目如WordPress
、Twitter
和Jquery
等使用,也擁有持續更新的完整生態圈和中文文檔。它是經過配置驅動——經過獲取到的JSON
配置執行操做,來流水線式執行相應任務。雖然在學習成本和執行效率上不出衆,但若是項目本來就是經過它自動化構建的,是沒有必要遷移到其它工具的。
// Grunt 的配置驅動示例 module.exports = function(grunt) { grunt.initConfig({ jshint: { files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], options: { globals: { jQuery: true } } }, watch: { files: ['<%= jshint.files %>'], tasks: ['jshint'] } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['jshint']); };
Gulp
是新型的構建工具,雖與Grunt
的功能相同,但其構建過程卻有三大優點。
代碼驅動即經過執行實際代碼驅動程序執行,與常見的配置驅動不一樣(Webpack
、Rollup
和Grunt
等都是配置驅動)。從任務流構建的角度上看,代碼驅動相比配置驅動有三點好處:一是高度的靈活;二是沒有過多的配置項,減小學習成本;三是更方便錯誤的判定和異常狀況的調試。
// Gulp 的代碼驅動示例 gulp.src('./client/templates/*.jade') .pipe(jade()) .pipe(gulp.dest('./build/templates')) .pipe(minify()) .pipe(gulp.dest('./build/minified_templates'));
Gulp
做爲後來者,充分利用NodeJS
流的思想進行IO
操做,極大增長了大型項目的構建速度。比方說轉化Scss
成Css
,Grunt
的操做流程是:讀取Scss
文件、轉化成Css
、存儲到磁盤,讀取Css
、壓縮處理最後存儲到磁盤;而Gulp
得操做是:讀取Scss
文件、轉化成Css
、壓縮處理最後存儲到磁盤。一步到位,無需屢次的IO
操做。
Gulp
有十分精簡的API
。你能想到各類類型的任務,基本是經過僅有的五個可鏈式操做的方法實現的嗎?不只僅是學習和使用方便,編寫後的功能也是一目瞭然。雖然代碼驅動相比配置驅動,須要本身寫的代碼增長,但一是沒增長難度只是函數名的屢次重寫,二是相對代碼驅動的好處來講能夠忽略。
集合型工具類即是常說的腳手架,也能夠看做是以模塊化或任務流工具爲主體的,各種經常使用工具的高度封裝。它是一個開箱便可用的集合體,相似先後端同構時代的後端框架。它會根據你的選擇,生成一個完整的、已配置好各種工具的、具備某些特定代碼約定的項目框架。這些配置幾乎包攬前端開發的整個流程,甚至能夠集成自動化部署等後端接口。
React CLI | Vue CLI | Angular CLI
集合型工具通常爲單頁面應用服務,而單頁面應用須要使用某個前端框架。不管你是用React
、Vue
或Angular
,仍是其它框架,首先得想到它是否有官方腳手架。好比Vue
有Vue CLI
。通常推薦有官方腳手架的直接使用官方的。由於現代前端框架通常不單獨運行,需結合官方提供的其它工具,好比路由、狀態管理等。並且各個框架及配件更新不斷,每次更新均可能致使與其它插件的兼容問題,新的功能可能須要某些特定插件才能發揮做用。這是一項工程,僅靠我的或某些團體很難照顧周全的。而各個框架又都有意識的經過官方腳手架來充分展現新的特性,下降學習和使用的成本。咱們何樂而不爲呢?
Yeoman
是一個專爲現代前端而生的、靈活通用的腳手架工具。
它的運做方式和其它腳手架不一樣。在安裝好CLI
後,須要找到一個符合要求的Generator
(一個npm
包,至關於腳手架),使用Yeoman
運行安裝,生成初始化的項目。你也能夠自行配置,使用Yeoman
封裝成符合特定需求的Generator
,併發布出去。等到下次,其餘人或你本身,須要生成符合此要求的項目時,即可以直接安裝並使用Yeoman
生成。
這樣有明顯的兩點好處:一是節省體力。在開始一個有特定需求的新項目時,若是有老項目可借鑑,通常會直接複製相關文件。但這樣的複製文件可能不純粹,即增長體積又帶來安全隱患。二是在社區的支持下,不少有特殊要求的腳手架,早已有人解決併發布成Generator
,是不必本身動手的。
百度 - FIS - 官網 | GitHub
微信 - WeFlow - 官網 | GitHub
京東 - Athena - 官網 | GitHub
餓了麼 - Cooking(名字與公司的性質相得益彰) - 官網 | GitHub
做爲程序員或至各行各業,在與年齡增加速度至關的壓力下,工資的高低天然成爲平常性的評定標準。但在同行老友的酒桌上或某個太陽異常溫煦下的小道上,能使本身爲本身而不是其餘事驕傲的,也確定是「老子以前作過些什麼」之類的實際付出而不是物質方面的得到。所以可以成爲被公司支持的、被衆多人使用的、開源框架維護團隊中的程序員,多少是更爲幸福的一類。
這些由國內各個前端團隊開發的集合型腳手架,都是基於自用在實踐中獲得的最爲符合自己需求的產品。裏面的包含內容十分豐富,不只僅是這以上提到的前端本職工做,還有與後端的集成方案或自動化部署配置等。且流程簡化,開箱便可使用。不過這些筆者都沒用過,也沒有打算用。不是打趣,緣由很現實,有識之士能夠在文章下留言。不用卻依然寫出的緣由卻是簡單:宣傳,宣傳即讚許和期盼;湊數,湊到13種好立個多少浮誇的標題。
我的觀點,不喜請噴,但要和善可親。
若是是使用某個前端框架開發應用程序,推薦框架官方的腳手架。若是是本身頭腦發熱想開源個JS
庫,推薦Rollup
打包。若是不是模塊化項目,又須要自動化處理一些事情,推薦Gulp
做爲構建工具。若是項目有特殊要求或做爲核心的部件比較稀有,能夠先查看Yeoman
上是否有符合要求的Generator
,沒有就只能自食其力。最後若是你處在已有本身腳手架的公司(好比餓了麼),可能要按規章制度使用Cooking
爲本身的仕途烹煮些吃食。肚子真餓,這種宣傳餓了麼會返優惠券嗎?
最後,若是是自食其力的搭建前人沒有的腳手架,推薦使用Yeoman
發佈,方便你我他。
原文地址: