Gulp.js----比Grunt更易用的前端構建工具

龍恩0707發表於2014-11-02

Gulp.js----比Grunt更易用的前端構建工具

  Grunt一直是前端構建工具,然而他也不是毫無缺陷的,gulp的作者 Eric Schoffstall 在他介紹 gulp.js 的 presentation 中總結了 Grunt 的幾點不足之處:

  1. 外掛很難遵守單一職責。因為 Grunt 的 API 設計缺憾,使得許多外掛不得不負責一些和其主要任務無關的事情。比如說要對處理後的檔案進行更名操作,你可能使用的是 uglify 外掛,也有可能使用的是 concat 外掛(取決於工作流的最後一個環節是誰)。
  2. 用外掛做一些本來不需要外掛來做的事情。因為 Grunt 提供了統一的 CLI 入口,子任務由外掛定義,由 CLI 命令來呼叫執行,因此哪怕是很簡單的外部命令(比如說執行 karma start)都得有一個外掛來負責封裝它,然後再變成 Grunt CLI 命令的引數來執行,多此一舉。
  3. 試圖用配置檔案完成所有事,結果就是混亂不堪。規模較大,構建/分發/部署流程較為複雜的專案,其Gruntfile 有多龐雜相信有經歷的人都有所體會。而 gulp.js 奉行的是“寫程式而不是寫配置”,它走的是一種 node way
  4. 落後的流程控制產生了讓人頭痛的臨時檔案/資料夾所導致的效能滯後。這是 gulp.js 下刀子的重點,也是本標題裡“流式構建”所解決的根本問題。流式構建改變了底層的流程控制,大大提高了構建工作的效率和效能,給使用者的直觀感覺就是:更快。

 Gulp相對於Grunt有五大優勢

      1. 使用 gulp.js,你的構建指令碼是程式碼,而不是配置檔案;

      2. 使用標準庫(node.js standard library)來編寫指令碼;

      3. 外掛都很簡單,只負責完成一件事.

      4. 任務都以最大的併發數來執行;

      5. 輸入/輸出(I/O)是基於“流式”的。

 下面我們先來看看在專案中如何使用Gulp來構建專案的吧!在構建之前,我們先來安裝下Gulp。

一:Gulp安裝-命令列工具。全域性安裝gulp  命令:npm install -g gulp 如下:

 

 如上,說明gulp已經安裝完成!

 二:專案demo演示

    1. 進入專案gulp的根目錄下,如下所示:

    

如上,是我專案gulp檔案。

       1. 在專案的根目錄下看有沒有package.json,如果沒有的話,我們需要執行下命令 npm init,  如下所示:

       

      之後在專案跟路徑下生產package.json檔案.

      2. 在專案檔案gulp下安裝為開發的依賴元件,執行命令:npm install --save-dev  gulp  如下所示:

      

      執行完成後,在根目錄下生產node_modules檔案,如下所示:

     

    3. 在專案的跟路徑下新建Gulpfile.js,如下所示:

     

    我們可以給Gulpfile.js的初始內容為:

  var gulp = require('gulp');
  gulp.task('default', function () {});

4. 執行gulp命令,如下所示:


上面是最基本的執行操作,下面我們來看一個具體的demo吧,還是如上的專案gulp檔案,我們現在的需求是想把gulp專案檔案下的src所有js檔案合併到dist目錄下的build.js,壓縮後的檔案為build-min.js。
在這之前,我們需要安裝如下外掛:
1. 語法檢查(gulp-jshint).
2. 合併檔案(gulp-concat).
3. 壓縮程式碼(gulp-uglify).

一:語法檢查 執行命令:npm install gulp-jshint --save-dev 如下圖所示:

二:合併檔案 執行命令:npm install gulp-concat  --save-dev  如下圖所示:

三:壓縮程式碼 執行命令:npm install gulp-uglify --save-dev 如下圖所示:

外掛裝完成後,我們可以看看根目錄下多了幾個外掛,如下所示:

其中gulp-rename我們去掉,不要的。

四:在專案的根目錄下建立Gulpfile.js檔案,內容如下:

var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

// 語法檢查
gulp.task('jshint', function () {
    return gulp.src('src/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'));
});

// 合併檔案之後壓縮程式碼
gulp.task('minify', function (){
     return gulp.src('src/*.js')
        .pipe(concat('build.js'))
        .pipe(gulp.dest('dist'))
        .pipe(uglify())
        .pipe(rename('build.min.js'))
        .pipe(gulp.dest('dist'));
});

// 監視檔案的變化
gulp.task('watch', function () {
    gulp.watch('src/*.js', ['jshint', 'minify']);
});

// 註冊預設任務
gulp.task('default', ['jshint', 'minify', 'watch']);

最後在命令列下,執行gulp命令即可。如下所示:

現在我們回到目錄下,可以看到如下所示:

如上Gulpfile.js,我們可以看到,基本上所有的任務都是這個模式。

 gulp.task(“任務名稱”,function(){

      return gulp.src(“檔案”)

      .pie(…)

     .pie(….)

 })

獲取要處理的檔案,傳遞給下一個環節處理,然後把返回的結果繼續傳給下一個環節,直到所有環節結束,pipe就是stream模組裡負責傳遞流資料的方法而已。

下面我們來看看gulp簡單的API,如下:

   1. gulp.task(name[,deps],fn) 註冊任務。

name: 是任務名稱,deps是可選的陣列,列出需要在本任務執行要執行的任務,fn是任務體,這是gulp.js的核心,比如下面是非常簡單的任務函式:

     gulp.task(“test”,function(){console.log(“111”)});

task方法還可以指定按順序執行的一組任務,如下:

    gulp.task(“build”,[‘css’,’js’,’java’]);

上面的程式碼先指定build任務,它按次序有css,js,java三個任務組成,注意:每個任務都是非同步呼叫,所以沒有辦法保證是那個任務先執行完。

如果希望要按照嚴格的順序執行完,可以如下寫程式碼:

gulp.task(‘css’,[‘js’],function(){});

如上程式碼表明:css的任務依賴於js,所以css一定會在js執行完成後在執行。

如果一個任務名字為default,它表示預設任務,在命令列中直接執行gulp即可。

    gulp.task(‘default’,function(){});

   2.gulp.src(globs[,options]):指明原始檔的路徑,options是可選的。

   有以下幾種形式:

   1.js/app.js 指明確切的檔名。

   2.js/*.js 某個目錄所有字尾名為js的檔案。

   3.js/**/*.js 某個目錄及其所有子目錄中的所有字尾名為js的檔案。

   4.!js/app.js 除了js/app.js以外的所有檔案

   5. *.+(js|css) 匹配專案的根目錄下,所有字尾名為js或css的檔案。

  Src方法的引數還可以是一個陣列,用來指定多個成員,如下:

    gulp.src([‘js/**/*.js’,!js/app.js]).

  3. gulp.dest(path) 指明任務處理後的目標輸出路徑。

  4.gulp.watch(globs[,options],task)/gulp.watch(globs[,options,cb]),監聽檔案的變化並執行相應的任務。

如上gulpfile.js程式碼,我監聽了jshint及minify程式碼,只要語法錯誤就會在命令列給出提示:如下所示:

官網有更多的關於gulp外掛(http://gratimax.net/search-gulp-plugins/) 我們可以根據自己的需求,來需要某個模組,註冊任務和執行還是上面一樣的。

相關文章