Gulp使用入門

jopen 9年前發布 | 10K 次閱讀 前端技術 gulp

Gulp使用入門

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

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

Grunt 通過 CLI 配合配置文件 gruntfile.js 去完成自動化構建任務,社區有非常多的 Grunt 插件,比如 concat(合并文件)、 uglify(js壓縮),只需要在 gruntfile.js 中配置好路徑等一些參數,運行以下命令就可以自動執行。

grunt takeName

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

  • 使用方便通過代碼優于配置的策略,Gulp 可以讓簡單的任務簡單,復雜的任務更可管理。

  • 構建快速通過流式操作,減少頻繁的 IO 操作,更快地構建項目。

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

  • 易于學習少量的API,掌握 Gulp 可以毫不費力。構建就像流管道一樣,輕松加愉快。

Gulp實現

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

Gulp使用入門

orchestrator

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

Gulp使用入門

一個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 讀寫文件流,如圖:

Gulp使用入門

glob-stream

大家可能有疑問,讀寫文件流,為什么不用 nodejs 內核的 steam 類來讀寫呢,騷安勿燥,Gulp 既然是基于 nodejs 構建,最終自然也是依賴 nodejs 內核實現它的功能的。

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

Gulp使用入門

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

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

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!