Gulp學習筆記

P1 簡介

gulp是基于Nodejs的自動任務運行器, 它能自動化地完成 javascript/coffee/sass/less/html/image/css 等文件的的測試、檢查、合并、壓縮、格式化、瀏覽器自動刷新、部署文件生成,并監聽文件在改動后重復指定的這些步驟。在實現上,她借鑒了Unix操作系統的管道(pipe)思想,前一級的輸出,直接變成后一級的輸入,使得在操作上非常簡單。通過本文,我們將學習如何使用Gulp來改變開發流程,從而使開發更加快速高效。

gulp 和 grunt 非常類似,但相比于 grunt 的頻繁 IO 操作,gulp 的流操作,能更快地更便捷地完成構建工作。

P2 安裝

可替換淘寶鏡像:npm install cnpm -g --registry=https://registry.npm.taobao.org

2.1 全局安裝 gulp:

$ npm install -g gulp

查看是否正確安裝:命令提示符執行gulp -v,出現版本號version 3.9.1即為正確安裝。
如果顯示'glup' 不是內部或外部命令,也不是可運行的程序或批處理文件。,請確定你是否打對字,是gulp,而不是glup!!!這里我故意打錯字你也發現不了。

2.2 作為項目的開發依賴(devDependencies)安裝:

$ npm install --save-dev gulp

P3 Gulp API整理

gulp只有四個API: taskwatchsrc,和 dest

3.1 gulp.task(name[, deps], fn)

name:任務名;
deps:StringArray(可選),一個包含任務列表的數組,這些任務會在你當前任務運行之前完成;
fn:任務操作函數function() {}.
//執行完one, two, three任務后再執行four
gulp.task('four', ['one', 'two', 'three'], function() {
    return gulp.src(path)
        .pipe(someplugin());
    //或其他事
});

3.2 gulp.src(globs[, options])

src方法是指定需要處理的源文件的路徑,gulp借鑒了Unix操作系統的管道(pipe)思想,前一級的輸出,直接變成后一級的輸入,gulp.src返回當前文件流至可用插件;

globs:String 或 Array,需要處理的源文件匹配符路徑

**通配符路徑匹配: **

  • src/a.js:指定具體文件
  • *:匹配所有文件 src/*.js(包含src下的所有js文件)
  • **:匹配0個或多個子文件夾 src/**/*.js(包含src的0個或多個子文件夾下的js文件);
  • {}:匹配多個屬性 src/{a,b}.js(包含a.js和b.js文件) src/*.{jpg,png,gif}(src下的所有jpg/png/gif文件);
  • !:排除文件 !src/a.js(不包含src下的a.js文件);
var gulp = require('gulp'),
    less = require('gulp-less');
 
gulp.task('testLess', function () {
    //gulp.src('less/test/style.less')
    gulp.src(['less/**/*.less','!less/{extend,page}/*.less'])
        .pipe(less())
        .pipe(gulp.dest('./css'));
});
options: (可選) Object,有3個屬性buffer、read、base
  • options.bufferBoolean 默認:true 設置為false,將返回file.content的流并且不緩沖文件,處理大文件時非常有用;
  • options.readBoolean 默認:true 設置false,將不執行讀取文件操作,返回null;
  • options.baseString 設置輸出路徑以某個路徑的某個組成部分為基礎向后拼接,具體看下面示例:
gulp.src('client/js/**/*.js') 
  .pipe(minify())
  .pipe(gulp.dest('build'));  // Writes 'build/somedir/somefile.js'

gulp.src('client/js/**/*.js', { base: 'client' })
  .pipe(minify())
  .pipe(gulp.dest('build'));  // Writes 'build/js/somedir/somefile.js'

異步任務支持
只有當fn接受一個 callback,或者返回一個 promise 或 stream任務 才可以異步執行,且task默認以最大的并發數執行,即gulp 會一次性運行所有的 task 并且不做任何等待。


//接受一個 callback
var exec = require('child_process').exec;
gulp.task('jekyll', function(cb) {
  // 編譯 Jekyll
  exec('jekyll build', function(err) {
    if (err) return cb(err); // 返回 error
    cb(); // 完成 task
  });
});

//返回一個 stream
gulp.task('somename', function() {
  var stream = gulp.src('client/**/*.js')
    .pipe(minify())
    .pipe(gulp.dest('build'));
  return stream;
});

//返回一個 promise
var Q = require('q');
gulp.task('somename', function() {
  var deferred = Q.defer();
  // 執行異步的操作
  setTimeout(function() {
    deferred.resolve();
  }, 1);
  return deferred.promise;
});

當然,如果你想要任務按照一定的順序執行。例如有兩個task,"one" 和 "two",在 "one" 中返回一個cb,或stream,promise,讓系統知道什么時候它會執行完畢; 在 "two" 中添加提示告訴系統 "two" 需要依賴 "one" 完成,即下面給出的栗子:

var gulp = require('gulp');

// 返回一個 callback,因此系統可以知道它什么時候完成
gulp.task('one', function(cb) {
    // 做一些事 -- 異步的或者其他的
    cb(err); // 如果 err 不是 null 或 undefined,則會停止執行,且注意,這樣代表執行失敗了
});

// 定義一個所依賴的 task 必須在這個 task 執行之前完成
gulp.task('two', ['one'], function() {
    // 'one' 完成后
});

gulp.task('default', ['one', 'two']);

3.3 gulp.dest(path[, options])

dest方法是指定處理完后文件輸出的路徑

path:String or Function 指定文件輸出路徑,或者定義函數返回文件輸出路徑亦可
options:Object,有2個屬性cwd、mode
  • options.cwdString 默認:process.cwd():當前腳本的工作目錄的路徑 當文件輸出路徑為相對路徑將會用到
  • options.modeString 默認:0777 指定被創建文件夾的權限

3.4 gulp.watch(glob [, opts], tasks)orgulp.watch(glob [, opts, cb])

watch方法是用于監聽文件變化,文件一修改就會執行指定的任務

glob: String or StringArray 需要處理的源文件匹配符路徑。
opts: Object(可選) 具體參看 gaze
tasks: StringArray 需要執行的任務的名稱數組;
cb(event): Function() 每次文件變化執行的回調函數;
  • event.type: String 發生的變動的類型:added, changed 或者 deleted
  • event.path: String 觸發了該事件的文件的路徑。

P4 新建gulpfile.js文件

說明:gulpfile.js是gulp項目的配置文件,是位于項目根目錄的普通js文件(其實將gulpfile.js放入其他文件夾下亦可)

我們將要使用Gulp插件來完成我們以下任務:

  • sass的編譯(gulp-sass)
  • 自動添加css前綴(gulp-autoprefixer)
  • 壓縮css(gulp-minify-css)
  • js代碼校驗(gulp-jshint)
  • 合并js文件(gulp-concat)
  • 壓縮js代碼(gulp-uglify)
  • 壓縮圖片(gulp-imagemin)
  • 自動刷新頁面(gulp-livereload)
  • 圖片緩存,只有圖片替換了才壓縮(gulp-cache)
  • 更改提醒(gulp-notify)
  • 修改文件名(gulp-rename)

安裝這些插件需要運行如下命令:

npm install gulp-sass gulp-autoprefixer gulp-minify-css gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-livereload gulp-cache --save-dev
//成功安裝后在package.json中出現版本信息
{
"devDependencies": {
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^3.1.1",
    "gulp-cache": "^0.4.6",
    "gulp-concat": "^2.6.1",
    "gulp-imagemin": "^3.2.0",
    "gulp-jshint": "^2.0.4",
    "gulp-livereload": "^3.8.1",
    "gulp-minify-css": "^1.2.4",
    "gulp-notify": "^3.0.0",
    "gulp-rename": "^1.2.2",
    "gulp-sass": "^3.1.0",
    "gulp-uglify": "^2.1.2"
  }
}

更多插件請點這里 gulp.js插件

4.1 加載插件:

// Load plugins
var gulp = require('gulp'),
    sass = require('gulp-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    minifycss = require('gulp-minify-css'),
    jshint = require('gulp-jshint'),
    uglify = require('gulp-uglify'),
    imagemin = require('gulp-imagemin'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),
    notify = require('gulp-notify'),
    cache = require('gulp-cache'),
    livereload = require('gulp-livereload');

4.2 建立任務:

4.2.1 編譯sass、自動添加css前綴和壓縮

首先我們編譯sass,添加前綴,保存到我們指定的目錄下面,還沒結束,我們還要壓縮,給文件添加 .min 后綴再輸出壓縮文件到指定目錄,最后提醒任務完成了:

// Styles任務
gulp.task('styles', function() {
    //編譯sass
    return gulp.src('stylesheets/main.scss')
        .pipe(sass())
        //添加前綴
        .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
        //保存未壓縮文件到我們指定的目錄下面
        .pipe(gulp.dest('stylesheets'))
        //給文件添加.min后綴
        .pipe(rename({ suffix: '.min' }))
        //壓縮樣式文件
        .pipe(minifycss())
        //輸出壓縮文件到指定目錄
        .pipe(gulp.dest('assets'))
        //提醒任務完成
        .pipe(notify({ message: 'Styles task complete' }));
});

4.2.2 js代碼校驗、合并和壓縮

// Scripts任務
gulp.task('scripts', function() {
    //js代碼校驗
    return gulp.src('javascripts/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        //js代碼合并
        .pipe(concat('all.js'))
        //給文件添加.min后綴
        .pipe(rename({ suffix: '.min' }))
        //壓縮腳本文件
        .pipe(uglify())
        //輸出壓縮文件到指定目錄
        .pipe(gulp.dest('assets'))
        //提醒任務完成
        .pipe(notify({ message: 'Scripts task complete' }));
});

4.2.3 圖片壓縮

// Images
gulp.task('images', function() {
    return gulp.src('images/*')
        .pipe(cache(imagemin({ 
            optimizationLevel: 3, //類型:Number默認:3取值范圍:0-7(優化等級)
            progressive: true, //類型:Boolean 默認:false 無損壓縮jpg圖片
            interlaced: true, //類型:Boolean 默認:false 隔行掃描gif進行渲染
            multipass: true //類型:Boolean 默認:false 多次優化svg直到完全優化
            })))
        .pipe(gulp.dest('images'))
        .pipe(notify({ message: 'Images task complete' }));
});

4.2.4 事件監聽

// Watch
gulp.task('watch', function() {
    // Watch .scss files
    gulp.watch('stylesheets/*.scss', ['styles']);
    // Watch .js files
    gulp.watch('javascripts/*.js', ['scripts']);
    // Watch image files
    gulp.watch('images/*', ['images']);
    // Create LiveReload server
    livereload.listen();
    // Watch any files in assets/, reload on change
    gulp.watch(['assets/*']).on('change', livereload.changed);
});

4.2.5 定義默認任務

栗子里的第二個參數是一個包含任務列表的數組,這些任務會在你當前任務運行之前完成。

gulp.task('default', ['styles', 'scripts', 'images', 'watch'], function() {
    console.log('Everthing is done!');
});

P5 運行gulp

5.1 命令提示符執行

  • 命令提示符執行gulp 任務名稱, 如gulp styles
  • 當執行gulp defaultgulp將會調用default任務里的所有任務

5.2 使用WebStorm運行gulp任務

將項目導入WebStorm,右鍵gulpfile.js 選擇“Show Gulp Tasks”打開Gulp窗口,若出現“No task found”,選擇右鍵”Reload tasks”,雙擊運行即可。

參考文檔

一點
gulp API 文檔
前端構建工具gulp入門教程1
前端構建工具gulp入門教程2

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

推薦閱讀更多精彩內容