Gulp挑戰Grunt,背后的哲學

[按:網上介紹Gulp和Grunt安裝使用的文章很多,甚少比較二者的思路,連官方文檔都語焉不詳。我在此做一個粗陋的對比,希望能提綱挈領,加深讀者對這兩個工具的理解。]

做過點兒正經開發的同學都知道,構建工具必不可少。C時代的Make、Java的Ant、Ruby的Rake……沒有這些工具,一遍遍地點選輸入,準煩死你。

在前端和Node JS的開發中,最普及的構建工具就是Grunt。它的功能說來簡單,就是管理一系列的Task。大部分的Task都是第三方的插件,安裝好對應的NPM包,再loadNpmTasks就可以用了。

Grunt的配置文件Gruntfile,主要包含兩部分:

  • 配置每個Task,包括文件從哪里,到哪里去,還有一些處理的選項

  • 自己寫一些簡單的Task,把第三方插件提供的Task組合起來

別看這兩個事兒,輕輕松松幾百行出來了。每個Task的配置,各有各的規矩,還牽扯到插件間的配合。反正我從seed庫開始做新項目的時候,基本不敢改原來的Gruntfile,很多用不上的功能也擱那兒。留意了一下很多開源項目的Gruntfile,也都臃腫雜亂,好不到哪兒去。

Gruntfile維護起來那么困難,有幾個原因:

  • 配置和運行分離
    程序員都知道,變量的聲明和使用挨在一起,最方便理解和修改。但Gruntfile里,配置Task和調用它們的地方離得很遠,極大地增加了心智負擔。

  • 每個插件做的事太多
    每個Task的結果必須寫到磁盤文件,另一個Task再讀,損害性能倒是小事,更麻煩的是讓整個過程變復雜了。
    就像一個個小作坊,來料加工又返回給客戶,這中間的溝通成本、出錯機會都大大增加。

  • 配置項過多
    做事多了,配置項自然也多。至少輸入和輸出的位置得配吧。每個插件的配置規則還不盡相同。用每個插件,都得去學習一番。

Gulp應運而生。

恐怕沒幾個IT人不知道Unix管道的概念。前一級的輸出,直接變成后一級的輸入。把簡單的工具組合起來,優雅地解決復雜的問題。聽起來那么熟悉呢?是的,Gulp就把這種思維用在構建過程中。

Gulp基于Node JS的一個機制,叫做stream,有點類似C++中的stream。在Node中,文件訪問、輸入輸出、HTTP連接,都是stream。Gulp的每個插件從stream中讀取輸入,做一些處理,再輸出到stream中。

每個插件不是拿來獨立使用的。相反,它專注于完成單一職責。只有把合適的插件組合起來,才能完成具體的Task。引用官方的例子,看看一個典型的Task長什么樣(略有刪減):

var paths = {
  scripts: ['client/js/**/*.coffee', '!client/external/**/*.coffee']
};

gulp.task('scripts', ['clean'], function() { // 可以依賴于其它task
  return gulp.src(paths.scripts) // 指定輸入
      .pipe(coffee()) // 環節一
      .pipe(uglify()) // 環節二
      .pipe(concat('all.min.js')) // 環節三
      .pipe(gulp.dest('build/js')); // 指定輸出
});

配置呢?不需要了。是不是行云流水,一氣呵成?

那我們再回頭來看看前面Grunt的幾個問題,Gulp是怎么解決的:

  • 配置和運行分離
    code over configuration,直接就在調用的地方配置。

  • 每個插件做的事太多
    單一職責,依靠組合來發揮作用。就像一條自動化生產線,上一道工序的產出直接交給下一步,效率不要太高。

  • 配置項過多
    既然大家都遵循同一個協議,很多配置就不需要了。

放大了看,Gulp像是一個非常貼近領域模型的DSL,而Grunt更像萬能的XML。哪個好用,無需多說。在我們制作DSL時,也有參考意義。

最后,舉一個Grunt很別扭,Gulp卻能優雅解決的例子。

做前端開發會用到一個功能叫usemin。我們HTML中會引用到很多css和js文件。發布時,這些文件要合并、壓縮、混淆,最后生成一兩個文件。為了讓修改過的代碼繞過瀏覽器的緩存機制,要根據文件內容hash出文件名。html文件里就要引用這些新的文件名。

比較一下grunt-usemingulp-usemin各自README的長度,就能看出區別。

grunt.registerTask('build', [
  'useminPrepare', // 準備
  'concat',
  'cssmin',
  'uglify',
  'filerev',
  'usemin' // 執行
]);

grunt-usemin分成兩步:

  • 先從html文件中收集需要處理的js和css,傳給后續的一堆任務
    它本身并不知道在實際中會調用哪些其它Task,只能用一些hack,支持固定的幾個Task。而上面的每個Task,都有自己的配置項。要把這些配置項都列出來,實在太長了。

  • 真正執行,更新html文件里的js和css引用。

gulp-usemin就干凈得多,沒有絲毫多余的東西:

gulp.task('usemin', function() {
  gulp.src('./*.html')
    .pipe(usemin({
      css: [minifyCss(), 'concat'],
      html: [minifyHtml({empty: true})],
      js: [uglify(), rev()]
    }))
    .pipe(gulp.dest('build/'));
});

usemin不需要有minifyCssminifyHtmluglifyrev這幾個插件的任何知識,只要把對應的內容從stream丟出去就好。在用這些插件組裝task時才需要關心。

當前,Gulp的社區還遠不如Grunt成熟,有些功能的插件,Gulp可能就沒有。這其實不算很大的劣勢,只要足夠好用,追上來很快。而且,寫一個Gulp插件要比相應的Grunt插件短小得多!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容