Gulp 對如今的前端而言,是一個稍微老舊的工具了,可是,爲了複習之前學過的內容,仍是把它翻出來,放在本身的博客中。說不定哪天又用到了呢。javascript
須要說明的是,這裏使用的 Gulp 版本是 3.9.1
。
Gulp 是基於 Nodejs 的任務運行器,主要做用就是對代碼進行構建打包。說白了,就是將源代碼經過 Gulp 中流的操做,生成目標代碼。css
Gulp 借鑑了 Unix 操做系統中的管道思想,前一級的輸出做爲後一級的輸入,全部的操做都是經過 Nodejs 流的形式來進行操做。這種思想使操做變得簡單,爲後續的任務編寫打下基礎。前端
學習任何一門技術以前,首先要知道它的官網,Gulp 也不例外。在這裏把中文官網和英文官網一併放在下面,固然,最好是看英文官網,因此把英文官網放在了最上面。java
固然,該項目的 GitHub 地址也是須要知道在哪一個地方的,這樣方便查看源碼。閒着沒事的時候,也能夠看看源碼實現,提升一下本身的技術水平。node
在網上搜集 Gulp 相關教程的時候,發現了一個很好的網站,上面有一系列關於 Gulp 的文章。這個網站中講解 Gulp 仍是比較詳細的。能夠按照該網站中給出的教程,逐個學習。git
Gulp 的安裝依賴 Nodejs。在安裝 Gulp 以前,必定要確保已經安裝了 Nodejs。關於 Nodejs 的安裝過程,能夠參照 安裝 Nodejs。github
全局安裝 :npm
若是須要全局使用 Gulp,可使用全局安裝。json
$ npm install -g gulp-cli
全局安裝,能夠在終端中使用下面的命令查看當前的 Gulp 版本 :gulp
$ gulp -v [16:10:17] CLI version 1.4.0
經過全局安裝的方式,在存在 gulpfile.js 的地方,均可以使用 gulp 命令來執行任務。
# 如 gulpfile.js 中存在一個 default 的命令,就能夠經過下面的方式執行 $ gulp
項目依賴安裝 :
這個時候安裝的 Gulp 是在 package.json 中的 devDependencies 節點下的,由於 Gulp 是項目開發時使用的模塊,不是生產時使用的模塊。
在安裝的時候,能夠選擇使用 npm 的方式安裝,這種安裝方式最多見,可是通常安裝速度比較慢。
# 使用 npm 安裝 $ npm install --save-dev gulp
固然,也能夠選擇使用 yarn 的方式進行安裝,這種方式安裝比較快速,可是須要安裝 yarn。
# 使用 yarn 安裝 $ yarn add gulp -D
經過項目依賴來安裝的 Gulp,必須在項目的根目錄下執行,且根目錄中必須存在 gulpfile.js,執行 Gulp 任務的時候,須要使用 Gulp 工具在當前項目目錄中的相對路徑來調用。
# 如 gulpfile.js 中存在一個 default 的命令,就能夠經過下面的方式執行 $ ./node_modules/.bin/gulp
通常狀況下,不推薦使用全局的方式來安裝 Gulp。推薦使用項目依賴來安裝,而後再結合 package.json 來使用。
首先要經過安裝項目依賴的方式來安裝 Gulp :
$ yarn add gulp -D
因爲經過 Gulp 來執行任務,首先須要有一個 gulpfile.js 文件,所以,在執行任務以前,要建立 gulpfile.js 文件。文件建立完成以後,建立兩個任務。
// 在文件中必定要引入的模塊 var gulp = require('gulp'); // 將你的默認的任務代碼放在這 gulp.task('default', function() { console.log('default task ...'); }); // 自定義名稱的任務 gulp.task('demo',function(){ console.log('demo task ...'); });
任務建立完成以後,下面就是經過 Gulp 來執行任務了。執行任務以前,首先明白不一樣的任務。對於 Gulp 而言,自己存在一個名字爲 default 的任務,這個任務名在 Gulp 中已經內置了。除了 default 以外,其他全部的任務都是自定定義的任務,也就是說,除了 default 以外,任務名能夠自定義。
在上面的代碼中定義了兩個任務,其中 default 是默認任務,執行的時候比較方便,在 gulp 命令以後,不須要跟任何參數。
$ ./node_modules/.bin/gulp [14:50:11] Using gulpfile ~/Desktop/es/gulpfile.js [14:50:11] Starting 'default'... default task ... [14:50:11] Finished 'default' after 187 μs
可是,自定義的任務執行的時候,要在 Gulp 命令後跟上一個參數,這個參數是任務的名字。
$ ./node_modules/.bin/gulp demo [14:50:16] Using gulpfile ~/Desktop/es/gulpfile.js [14:50:16] Starting 'demo'... demo task ... [14:50:16] Finished 'demo' after 1.35 ms
輸出的日誌中,會把任務開始的時間以及結束的時間打印出來,開始時間和結束時間之間就是任務執行的過程。從某方面來說,這種輸出的日誌相似 HTML 中的標籤,存在開始標籤和結束標籤。固然,這只是一種類比。
須要補充的一點 : 若是須要使用 babel 來轉換 js 文件,爲了能使 babel 的配置文件可以正常讀取,通常會把gulpfile.js
從新命名爲gulpfile.babel.js
,這樣就能夠在gulpfile.babel.js
中使用 ES6 的最新語法了。
Gulp 的 API 設計也比較簡單,總共只有四個 gulp.src
gulp.dest
gulp.task
gulp.watch
。不多的 API,極大程度上縮減了記憶的成本,可是須要本身配置的內容相對而言就多了。
gulp.task
主要是用來定義任務的。
/** * 做用 : 定義一個任務 * @param {String} name 任務的名字,不要在任務名字中出現空格 * @param {Array} deps 可選參數,任務列表的數組,是當前任務執行前的依賴任務,數組的元素是任務名 * @param {Function} fn 定義任務所要執行的一些操做 */ gulp.task(name[, deps], fn)
對於第三個參數,須要說明一下。第三個參數能夠接收一個回調函數,也能夠返回一個 stream。
當接收一個回調函數的時候,必定要注意回調函數中的參數。
gulp.task('mytask', function (cb) { if (true) { cb(null); // 當回調函數的參數是 null 的時候,說明不會存在錯誤 } else { cb('存在錯誤'); // 當回調函數的參數不是 null 的時候,這個時候就是產生了錯誤 } });
返回一個 stream 流的時候,通常是經過 gulp 的 API 來獲取的。
gulp.task('mytask', function() { var stream = gulp.src('client/**/*.js') .pipe(gulp.dest('build')); return stream; });
gulp.src
主要做用就是用來讀取文件或者文件夾中的數據。
/** * 做用 : 讀取數據並返回一個流 * @param {String | Array} globs 參數是文件或者文件夾,支持相對路徑 * @param {Object} options 可選參數,任務列表的數組,是當前任務執行前的依賴任務,數組的元素是任務名 */ gulp.src(globs[, options])
其中 globs 的參數是 node-glob 模塊 的參數。詳細參數能夠到官網查看這個模塊,這裏只說明幾個特殊的匹配。
**
用於匹配文件夾,表示 0 個或者多個層級的目錄*
用於匹配文件名,表示 0 個或者多個字符!
排除符合規則的文件,!
必定要放在匹配規則以前若是要匹配 src 目錄下的全部 .js 文件,且排除 src 目錄下的全部如下劃線開頭的 .js 文件,就能夠寫成下面的形式 :
gulp.src(['./src/**/*.js', '!./src/**/_*.js'])
使用 options.base
能夠修改文件的目標路徑。在沒有指定該參數的時候,目標路徑是第一個匹配符以前的路徑。
gulp.task('default', function () { // 這個時候會把 ./src/one 替換成 ./build,也能夠理解成此時的 options.base 爲 ./src/one // 最終 .js 文件所在的路徑就是 ./build/*.js return gulp.src(['./src/one/*.js']) .pipe(gulp.dest('./build')); });
若是指定了 options.base
參數,那麼最終文件所在的路徑就會發生變化。
gulp.task('default', function () { // 最終 .js 會被拷貝到 ./build/one/*.js 中 return gulp.src(['./src/one/*.js'], { base: 'src' }) .pipe(gulp.dest('./build')); });
gulp.dest
用來指定文件最終被寫入的路徑。
/** * 做用 : 讀取數據並返回一個流 * @param {String} path 文件的目標路徑,這個只能指定文件夾,不能指定文件 * @param {Object} options 可選參數,通常不多使用,這裏再也不說明 */ gulp.dest(path[, options])
gulp.dest
的簡單使用實例。
gulp.task('default', function () { return gulp.src('./src*.js').pipe(gulp.dest('./build')); });
gulp.watch
用於監視文件變化,發現文件變化,則觸發某個操做。
/** * 做用 : 監視文件變化,發現文件變化,則觸發某個操做 * @param {String | Array} glob 通常是匹配文件 * @param {Object} opts 可選參數,通常不多使用,這裏再也不說明 * @param {Array} tasks 數組的參數是任務的名稱,表示文件變化觸發一個或多個任務 */ gulp.watch(glob [, opts], tasks)
我們如今看一個簡單的例子,.js 文件發生變化的時候,執行任務 one。
gulp.task('one', function () { console.log('one...'); }); gulp.task('default', function () { console.log('default ...'); }); gulp.watch('src/**/*.js', ['one']);
如今有一個需求,當某個 .js 文件發生變化的時候,須要獲取是哪一個文件發生了變化,那麼就須要增長監聽。
gulp.task('one', function () { console.log('one...'); }); gulp.task('default', function () { console.log('default ...'); }); gulp.watch('src/**/*.js', ['one']).on('change', function(event) { // event.path 表示文件的名稱 // event.type 指的是發生的變化 console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); });
Gulp 的進一步使用,能夠參照中文官網中的 gulp 技巧集。