歡迎來個人博客閱讀:《Gulp 基礎與原理》javascript
Gulp 是基於 NodeJS 的項目,一個用做自動化構建的工具,業界通常用來建造前端的工做流。css
它的核心原理其實很簡單,最主要是經過各類 Transform Stream 來實現文件的處理,而後再進行輸出。Transform Streams 是 NodeJS Stream 的一種,是可讀又可寫的,它會對傳給它的對象作一些轉換的操做。html
文件輸入 → Gulp 插件處理 → 文件輸出前端
原則上,gulp 能夠針對文件作任何有趣、有創造力事情。
而自動化構建,只是你們主要比較喜歡使用的方向。java
Gulp 的特色:node
自動化 - Gulp 爲你的工做流而服務,自動運行那些費事費力任務。git
平臺透明 - Gulp 被集成到各類 IDE 中,而且除了 NodeJS 以外,其餘如 PHP、.NET、Java 平臺均可以使用 Gulp。github
強大生態系統 - 你可使用 npm 上 2000+ 的插件來構造你的工做流。正則表達式
簡單 - Gulp 只提供幾個 API,這能夠很快地學習和上手。npm
$ npm install gulp-cli -g // 全局安裝 Gulp 命令行工具 $ npm install gulp -D // 在項目中,做爲 devDependencies 依賴安裝 gulp
在使用 CLI 工具的時候,會執行該文件,它是一個可執行的 NodeJS 文件。原理上,你能夠在裏面運行任何 NodeJS 代碼,而後經過調用 gulp 提供的 API,來執行 gulp 任務。gulpfile.js
文件通常都會放在項目的根目錄中。
一個使用 gulp-babel 插件來支持 es2015 語法的案例:
const gulp = require('gulp'); const babel = require('gulp-babel'); gulp.task('default', () => { gulp.src('src/app.js') .pipe(babel({ presets: ['es2015'] })) .pipe(gulp.dest('dist')); });
瞭解這些概念,對於瞭解 Gulp 的工做原理,和 API 的使用是頗有幫助的。
Glob 是一種用來匹配路徑與文件的模式。有點相似於正則表達式,可是語法又有點差別。
這種模式,被普遍用於命令行、Shell 等場景,你們熟悉的 .gitignore
文件也是使用這種模式。
各大語言都有對於 Glob 的實現,例如 Go 和 PHP 的 Glob
函數,Python 中的 glob
模塊。
而 NodeJS 的實現是 minimatch, 而在 Gulp 源碼中,就用了對 minimatch 進行封裝的 node-glob 模塊。
Gulp 的 API gulp.watch
和 gulp.src
都有用到 Glob 來匹配對應的路徑和文件。
下面是部分語法:
*
匹配該路徑段中 0 個或多個任意字符,
如:js/*.js
, 匹配 js 目錄下的全部 js 文件
?
匹配該路徑段中 1 個任意字符,
如:js/?.js
,匹配 js 目錄下全部名字只有 1 個字的 js
[...]
匹配該路徑段中在指定範圍內字符,
如:js/a[0-3].js
,匹配 js 目錄下 a 開頭,第二個字符爲 0-3 之間( 包括0和3 )的 js( a03.js不能被匹配到 )
!(pattern|pattern|pattern)
匹配除所給出的模型之外的狀況,
如:js/!(a|b).js
,匹配 js 目錄下名字中不包含 a ,也不包含 b 的全部文件.
?(pattern|pattern|pattern)
匹配所給出的模型中的 0 個或任意 1 個,
如:js/?(a|a2|b).js
, 匹配 js 目錄下 a.js , a2.js , b.js
+(pattern|pattern|pattern)
匹配所給出的模型中的 1 個或者多個,
如:js/+(a|a1|b).js
, 匹配 js 目錄下 a.js , a1.js , b.js , 或者 a, a1, b 這幾個字符的組合的 js , 好比 ab.js
*(pattern|pattern|pattern)
匹配所給出的模型中的 0 個或多個或任意個的組合.
如:js/*(a|a1|b).js
,匹配 js 目錄下 a.js, a1.js, b.js 或者 a, a1, b這幾個字符的組合的 js , 好比 ab.js
@(pattern|pat*|pat?erN)
匹配所給出的模型中的任意 1 個,
如:js/@(a|a1|b)
, 匹配 js 目錄下的 a.js, a1.js, b.js
**
與 *
同樣能夠匹配任何內容,但 **
不只匹配路徑中的某一段,並且能夠匹配 a/b/c
這樣帶有 /
的內容,因此,它還能夠匹配子文件夾下的文件.
如:js/**/*.js
,匹配 js 目錄下及子文件夾中全部的 js 文件。
更多 Glob 的知識和語法,能夠參考:
Glob - Wiki
Glob Primer
Vinyl 是 Gulp 自創的一種用來描述一個虛擬文件的類,其中主要包括文件的內容和文件的路徑兩大信息。vinyl 模塊,只是提供了一個類,而實現卻交由 vinyl-fs
Vinyl-fs,它主要的工做是接受 glob 模式的參數,而後讀取匹配的文件。而後利用 Vinyl 製做一個 Transform Stream,稱爲 Vinyl Stream 對象,並返回。
在 Gulp 中的 API gulp.src
、gulp.watch
、gulp.dest
都返回一個 Vinyl Stream 實例對象。Vinyl Stream 實例之間能夠經過管道( vinyl1.pipe(vinyl2)
)的形式來互相傳輸數據。
從 Gulp 的 源碼 中也能看出,這三個 API 都是由 vinyl-fs 提供所有的實現。
再一點是,從這兩個模塊的實現來看,Gulp 是把文件內容以 Buffer 的形式讀到內存中,而後再進行處理的。
Orchestartor,爲 gulp.task
提供了所有實現,這能夠從 源碼 中看出。
它爲 Gulp 提供了任務相關的功能,包括任務註冊、任務執行以及相對應的任務進度、錯誤監控等功能。
Orchestartor 模塊,只提供了一個 Orchestartor 類,該類的實例維護着一個 tasks 數組,該數組的內容就是一個咱們使用 gulp.task
時註冊的函數列表,以及函數的依賴和名字。
經過 源碼 中,能夠看到 tasks 的數據結構:
... this.tasks[name] = { fn: fn, // 任務的函數體 dep: dep, // 任務所依賴的其餘任務名稱 name: name // 該任務的名稱 }; ...
gulp.src:獲取文件
gulp.dest:寫入文件
gulp.tasks:註冊任務
gulp.watch:監控文件的改動
gulp.src( globs [, options] )
接收一個 globs 模式的對象,能夠是 Array 或者 String,返回一個 Vinyl Stream 實例。
而 options 有下面的值:
buffer - Boolean, 控制 file.contents
是返回 buffer 仍是 stream。
read - Boolean,控制是否讀取文件,若是 false,則 file.contents
爲 null
base - String,控制 glob 的 base,默認值是 glob 全部表達式的前置,例如 client/js/**/*.js
, base 值就爲 client/js/
。而 glob 在保存輸出路徑的時候,取的是 base 以後的路徑。因此能夠經過該值,來進行輸出路徑的改寫。
gulp.dest( path [, options] )
接收輸出路徑,返回一個 Vinyl Stream 實例。
而 options 有如下的值:
cwd - String, 默認值 process.pwd()
,輸出目錄的 cwd 參數,只在所給的輸出目錄是相對路徑時候有效。
mode - String,八進制權限字符,用以定義全部在輸出目錄中所建立的目錄的權限。
gulp.task( name [, deps ], fn )
定義一個使用 Orchestrator 實現的任務(task)。
參數的描述以下:
name - 任務名稱
deps - 是當前定義的任務須要依賴的其餘任務,爲一個數組。當前定義的任務會在全部依賴的任務執行完畢後纔開始執行。若是沒有依賴,則可省略這個參數
fn - 爲任務函數,咱們把任務要執行的代碼都寫在裏面。該參數也是可選的。
gulp.watch( glob [, opts ], tasks )
orgulp.watch( glob [, opts, cb ] )
用來監視文件的變化,當文件發生變化後,咱們能夠利用它來執行相應的任務。
各參數的描述以下:
glob - 爲要監視的文件 Glob 匹配模式。
opts - 爲一個可選的配置對象。
tasks - 爲文件變化後要執行的任務,爲一個數組
gulp-load-plugins:自動加載 package.json
中的 gulp 插件
gulp-rename: 重命名
gulp-uglify:文件壓縮
gulp-concat:文件合併
gulp-less:編譯 less
gulp-sass:編譯 sass
gulp-clean-css:壓縮 CSS 文件
gulp-htmlmin:壓縮 HTML 文件
gulp-babel: 使用 babel 編譯 JS 文件
gulp-jshint:jshint 檢查
gulp-imagemin:壓縮jpg、png、gif等圖片
gulp-livereload:當代碼變化時,它能夠幫咱們自動刷新頁面
更多插件,能夠搜索官方插件庫。