gulp vs. grunt

2018-06-09 17:14 更新

GulpGrunt都是用于前端開發(fā)的構(gòu)建工具(或者說它們是任務(wù)運行管理器更加合適一點)。其中Grunt的出現(xiàn)要比Gulp早不少時間,不過Gulp后來居上隱隱有取而代之的態(tài)勢。

下面我將會對grunt及gulp先做一個簡單的用法介紹,不過會著重介紹下gulp,最后再簡單的將兩者做一個對比。

grunt簡介

gruntjs中文社區(qū)介紹grunt是這么說的,JavaScript世界的構(gòu)建工具。

其實構(gòu)建工具基本上就是讓一些重復(fù)的任務(wù)自動化。我們先來上一個簡單使用grunt的例子來大概了解下grunt是怎么用的。

首先是安裝,grunt有一個對應(yīng)的grunt-cli,我們需要全局安裝這個cli,

~ npm install -g grunt-cli

然后切換到項目目錄,安裝grunt及用到的插件,因為是僅作示例,我這里就使用了一個插件。

~ cd <YOUR_PROJECT_DIR>
~ npm install gulp grunt-contrib-uglify --save-dev

然后創(chuàng)建Gruntfile.js文件,其內(nèi)容如下,

module.exports = function(grunt) {
    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
            },
            build: {
                src: 'src/*.js',
                dest: 'build/all.min.js'
            }
        }
    });
    // 加載包含 "uglify" 任務(wù)的插件。
    grunt.loadNpmTasks('grunt-contrib-uglify');
    // 默認(rèn)被執(zhí)行的任務(wù)列表。
    grunt.registerTask('default', ['uglify']);
};

從Gruntfile.js文件中可以看出文件內(nèi)容主要分為兩塊,第一塊是相關(guān)task的配置,第二塊是加載任務(wù)。

本示例中,我僅僅配置了一個叫做uglify的任務(wù),用于壓縮代碼文件。具體的策略是:壓縮src目錄下的所有js文件,然后將壓縮好的文件合并在一起輸入到dest目錄下的all.min.js文件中。(這里可以看出,這個uglify插件除了壓縮之外還做了合并的事。)

結(jié)果如下,

Running "uglify:build" (uglify) task
>> 1 file created.
Done, without errors.

更多的內(nèi)容,請參考grunt的官方文檔。

gulp簡介

gulp是一款開源的基于流的構(gòu)建工具,托管在github上,地址在這里,目前已經(jīng)有10000+個Star,相比grunt的近9000個Star,后來居上,發(fā)展勢頭很迅猛。

下面我們通過一個簡單的例子來領(lǐng)略下gulp的風(fēng)采。

首先是安裝,下面的兩種方式可以根據(jù)你的喜好和情況自由選擇,


~ npm install -g gulp


~ cd <YOUR_PROJECT_DIR>
~ npm install gulp --save-dev

然后是在項目的根目錄下創(chuàng)建Gulpfile.js文件,


var gulp = require('gulp');
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat');
gulp.task('default', function () {
    return gulp.src('./src/*.js')
        .pipe(uglify())
        .pipe(concat('all.min.js'))
        .pipe(gulp.dest('./build'));
});

最后就可以運行了,


~ gulp

結(jié)果如下,


[14:14:13] Using gulpfile D:\WebstormProjects\hello-gulp\gulpfile.js
[14:14:13] Starting 'default'...
[14:14:13] Finished 'default' after 37 ms

啊哈,是不是很簡單輕量呢?

輕量簡潔的API

gulp的API文檔中有對其API的詳細(xì)描述??偟膩碚f,gulp原生提供了四個api接口,

  1. gulp.src(globs[, options]) 指明源文件,所有g(shù)ulp的task都是從讀取源文件開始
  2. gulp.dest(path) 指明任務(wù)處理的目標(biāo)輸出路徑
  3. gulp.task(name[, deps], fn) 注冊任務(wù)
  4. gulp.watch 監(jiān)視文件改動并運行相關(guān)邏輯或者任務(wù)

稍微完整一些的示例

我們使用gulp來完成以下三個構(gòu)建任務(wù):1.語法檢查(gulp-jshint),2.合并文件(gulp-concat),3.壓縮代碼(gulp-uglify)。完整的代碼如下,


var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
// 語法檢查
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('all.js'))
        .pipe(gulp.dest('dist'))
        .pipe(uglify())
        .pipe(rename('all.min.js'))
        .pipe(gulp.dest('dist'));
});
// 監(jiān)視文件的變化
gulp.task('watch', function () {
    gulp.watch('src/*.js', ['jshint', 'minify']);
});
// 注冊缺省任務(wù)
gulp.task('default', ['jshint', 'minify', 'watch']);

除了watch任務(wù)外,基本上所有的任務(wù)單元都是這么樣的一個模式,


gulp.task('task-name', function () {
    var stream = gulp.src('...') // 流開始
        .pipe(...)
        .pipe(...)
        // 任務(wù)的最后一步
        .pipe(...);
    return stream;
});

所以,為什么說gulp是一種基于的構(gòu)建工具,從這里可以看出,每個任務(wù)從src讀取源文件生成流開始,中間通過pipe傳遞流,所有的任務(wù)步驟都是在流上做一些操作,最后將流通過dest輸出到目標(biāo)上。

gulp和grunt的差異對比

在github上有相當(dāng)一些項目是用grunt作為構(gòu)建工具的,觀察這些項目的Gruntfile.js文件,可以很容易發(fā)現(xiàn)大部分的Gruntfile.js都非常臃腫,有一大段一大段的嵌套配置結(jié)構(gòu),令人看起來很煩躁。這些冗余的Gruntfile.js文件其實維護(hù)起來并不是那么輕量的,主要體現(xiàn)在下面幾個方面,

  1. 配置和運行分離
  2. 大部分插件的職責(zé)不單一,做了不僅一件事
  3. 配置項過多,做的事情越多,配置增長的就越快,且越不可控制
  4. 任務(wù)執(zhí)行中會產(chǎn)生一些臨時文件,較頻繁的IO操作導(dǎo)致性能滯后

我們再來看看gulp中是如何解決這些問題的,

  1. gulp遵循code over configuration的原則,直接就在調(diào)用的地方配置
  2. gulp的插件嚴(yán)格遵循單一職責(zé)原則,一個插件僅作一件事,一個gulp一般只有20多行代碼就搞定
  3. gulp基于流的思想,并沒有過多的配置,任務(wù)更多的像是在寫代碼而不是定義配置
  4. 這個是grunt的致命傷,gulp的流式構(gòu)建改變了底層的流程控制,不再頻繁的去進(jìn)行IO操作了

參考列表


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號