重讀 Gulp

Gulp 簡介

Gulp 對如今的前端而言,是一個稍微老舊的工具了,可是,爲了複習之前學過的內容,仍是把它翻出來,放在本身的博客中。說不定哪天又用到了呢。javascript

須要說明的是,這裏使用的 Gulp 版本是 3.9.1

認識 Gulp

Gulp 是基於 Nodejs 的任務運行器,主要做用就是對代碼進行構建打包。說白了,就是將源代碼經過 Gulp 中流的操做,生成目標代碼。css

Gulp 借鑑了 Unix 操做系統中的管道思想,前一級的輸出做爲後一級的輸入,全部的操做都是經過 Nodejs 流的形式來進行操做。這種思想使操做變得簡單,爲後續的任務編寫打下基礎。前端

Gulp 資源

學習任何一門技術以前,首先要知道它的官網,Gulp 也不例外。在這裏把中文官網和英文官網一併放在下面,固然,最好是看英文官網,因此把英文官網放在了最上面。java

固然,該項目的 GitHub 地址也是須要知道在哪一個地方的,這樣方便查看源碼。閒着沒事的時候,也能夠看看源碼實現,提升一下本身的技術水平。node

在網上搜集 Gulp 相關教程的時候,發現了一個很好的網站,上面有一系列關於 Gulp 的文章。這個網站中講解 Gulp 仍是比較詳細的。能夠按照該網站中給出的教程,逐個學習。git

Gulp 入門

安裝 Gulp

Gulp 的安裝依賴 Nodejs。在安裝 Gulp 以前,必定要確保已經安裝了 Nodejs。關於 Nodejs 的安裝過程,能夠參照 安裝 Nodejsgithub

全局安裝 :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 的簡單使用

首先要經過安裝項目依賴的方式來安裝 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 的 API 設計也比較簡單,總共只有四個 gulp.src gulp.dest gulp.task gulp.watch。不多的 API,極大程度上縮減了記憶的成本,可是須要本身配置的內容相對而言就多了。

gulp.task

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

gulp.src 主要做用就是用來讀取文件或者文件夾中的數據。

/**
 * 做用 : 讀取數據並返回一個流
 * @param {String | Array} globs 參數是文件或者文件夾,支持相對路徑
 * @param {Object} options 可選參數,任務列表的數組,是當前任務執行前的依賴任務,數組的元素是任務名
 */
gulp.src(globs[, options])

其中 globs 的參數是 node-glob 模塊 的參數。詳細參數能夠到官網查看這個模塊,這裏只說明幾個特殊的匹配。

  1. ** 用於匹配文件夾,表示 0 個或者多個層級的目錄
  2. * 用於匹配文件名,表示 0 個或者多個字符
  3. ! 排除符合規則的文件,! 必定要放在匹配規則以前

若是要匹配 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

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

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 技巧集

相關文章
相關標籤/搜索