Gulp使用入門

做者:Jogis
原文連接:https://github.com/yesvods/Blog/issues/1
轉載請註明原文連接以及做者信息css

gulp

提到 Gulp,不得不說到的是較早的 JS 項目自動化構建工具——Grunt。前端

前端開發過程當中,特別是最近幾年多了 CoffeeScript、Sass、Less 等一些預編譯語言,不少代碼每次寫完須要手動到工做目錄去編譯才能執行。此外,項目預發佈時候須要進行 js、css 文件合併、壓縮、重命名等操做,實在是很繁瑣。此前不少工程師使用的是 Makefile 構建項目,可是這要求須要必定Linux基礎,並且編寫配置文件會增大很是多工做量, Grunt 的出現,解放了前端工程師的雙手=_=node

Grunt 經過 CLI 配合配置文件 gruntfile.js 去完成自動化構建任務,社區有很是多的 Grunt 插件,好比 concat(合併文件)、 uglify(js壓縮),只須要在 gruntfile.js 中配置好路徑等一些參數,運行如下命令就能夠自動執行。c++

grunt takeName

Gulp是一款 The streaming build system(流式構建系統),若是說 Grunt 是基於 gruntfile.js 任務執行器,Gulp 就是基於 NodeJS 的文件流任務執行器,比起 Grunt 有以下特色git

  • 使用方便
    經過代碼優於配置的策略,Gulp 可讓簡單的任務簡單,複雜的任務更可管理。github

  • 構建快速
    經過流式操做,減小頻繁的 IO 操做,更快地構建項目。npm

  • 插件高質
    Gulp 有嚴格的插件指導策略,確保插件能簡單高質的工做。gulp

  • 易於學習
    少許的API,掌握 Gulp 能夠絕不費力。構建就像流管道同樣,輕鬆加愉快。promise

Gulp實現

Gulp 主要 API 爲 gulp.src(使用glob模式匹配得到文件流集)、gulp.dest(輸出gulp文件流集到指定路徑,路徑指定相對於gulpfile.js配置文件)、gulp.watch(監聽glob模式匹配的文件集,有改動時執行相應gulp任務),如圖:瀏覽器

gulp實現

orchestrator

譯做管絃樂演奏家,大多數就是一個老頭拿着個小棍的形象,就像這樣:

orchestrator

一個npmjs模塊,就是一個以最大併發方式去排序或執行一系列的任務。這些任務就是咱們以後會用到的 Gulp 任務,好比說 css 命名的任務,裏面包括css的瀏覽器前綴添加、合併、壓縮等操做。orchestrator 經過實例化一個對象,在對象上調用 add 來添加特定命名的任務、添加任務時候能夠聲明任務依賴,好比:

var Orchestrator = require('orchestrator');
var orchestrator = new Orchestrator();
orchestrator.add('thing1', function(){
  // do stuff
});
orchestrator.add('thing2', function(){
  // do stuff
});
orchestrator.add('mytask', ['thing1','thing2'], function() {
  // Do stuff
});

以上代碼,添加了3個 Gulp 任務,mytask 任務依賴於 thing1 和 thing2 ,即必須執行完後面兩個任務,mytask才能執行,經過任務依賴,很容易理清和構建任務時候的執行順序。須要注意的是,在填寫 do stuff 時候,要確保其返回一個 promise 或者是 event stream(最經常使用),好比一個簡單的任務是這樣定義的:

var map = require('map-stream');

orchestrator.add('thing4', function(){
  var stream = map(function (args, cb) {
    cb(null, args);
  });
  // do stream stuff
  return stream;
});

或則是返回一個 promise:

var Q = require('q');

orchestrator.add('thing3', function(){
  var deferred = Q.defer();

  // do async stuff
  setTimeout(function () {
    deferred.resolve();
  }, 1);

  return deferred.promise;
});

orchestrator 調用 start 來執行特定名稱的任務,可一次執行多個:

orchestrator.start('one', 'two');

以上兩個是 orchestrator 最經常使用的用於實現 Gulp 的函數,除此以外,還有任務檢測,任務暫停,任務事件監聽,想詳細瞭解可訪問npmjs:https://www.npmjs.org/package/orchestrator

vinyl-fs

這是 Gulp 採用的一個虛擬文件系統,能夠讀取 glob 模式匹配到的文件並轉成文件流,能夠獲取文件流並轉成文件集。其中 vinyl-fs 使用 vinyl 虛擬文件描述類,來對 glob 匹配到的文件進行描述,所謂的描述,只是簡單的文件名與路徑,以及文件內容,能夠說是一個文件的封裝,能夠看看 vinyl 是如何描述一個或一組文件的:

var File = require('vinyl');

var coffeeFile = new File({
  cwd: "/",
  base: "/test/",
  path: "/test/file.coffee",
  contents: new Buffer("test = 123")
});

除了 vinyl ,vinyl-fs 還須要依賴 glob-stream 讀寫文件流,如圖:

vinyl

glob-stream

你們可能有疑問,讀寫文件流,爲何不用 nodejs 內核的 steam 類來讀寫呢,騷安勿燥,Gulp 既然是基於 nodejs 構建,最終天然也是依賴 nodejs 內核實現它的功能的。

只是,stream 類讀取文件流只針對一個文件路徑,glob-stream 就是實現從獲取 glob 模式匹配文件集,到轉換成文件路徑,再到讀取,仍是有一段距離的。如圖:

glob-stream

glob-stream 經過 minimatch 來進行 glob 模式匹配,經過其餘路徑模塊,得到一組文件路徑,而後就是 ordered-read-streams 發光發熱時候啦,對這組文件路徑一個個地讀啊,而後就得到一組文件流啦。

好啦,終於分析完 Gulp 的實現,經過對其中模塊的閱讀,其實 Nodejs 模塊有點像樂高積木,內核給出的就是最基本的積木啦,不過你能夠無限次使用它們,來堆出一個個小的物體,經過小小的物體組合,來組成很是徇麗多姿的樂高做品啦~

固然,也是有一些 c++ 實現的nodejs模塊,主要是用於一些須要高性能運算的地方,不過npmjs.org上介紹到的模塊,大部分的依賴都是基於 nodejs 內核實現滴。

相關文章
相關標籤/搜索