任務(Tasks) 每一個 gulp 任務都是一個異步 JavaScript 函數,它要麼接受一個錯誤優先回調,要麼返回一個流、promise、事件發射器、子進程或observable。因爲一些平臺限制,不支持同步任務。javascript
gulp 再也不支持同步任務(Synchronous tasks)了。由於同步任務經常會致使難以調試的細微錯誤,例如忘記從任務(task)中返回 stream。css
當你看到 "Did you forget to signal async completion?" 警告時,說明你並未使用前面提到的返回方式。你須要使用 callback 或返回 stream、promise、event emitter、child process、observable 來解決此問題。java
src() 接受 glob 參數,並從文件系統中讀取文件而後生成一個 Node 流(stream)。它將全部匹配的文件讀取到內存中並經過流(stream)進行處理。npm
流(stream)所提供的主要的 API 是 .pipe() 方法,用於鏈接轉換流(Transform streams)或可寫流(Writable streams)。gulp
當它接收到經過管道(pipeline)傳輸的文件時,它會將文件內容及文件屬性寫入到指定的目錄中。gulp 還提供了 symlink() 方法,其操做方式相似 dest(),可是建立的是連接而不是文件( 詳情請參閱 symlink() )。 大多數狀況下,利用 .pipe() 方法將插件放置在 src() 和 dest() 之間,並轉換流(stream)中的文件。api
src() 也能夠放在管道(pipeline)的中間,以根據給定的 glob 向流(stream)中添加文件。新加入的文件只對後續的轉換可用。若是 glob 匹配的文件與以前的有重複,仍然會再次添加文件。 這對於在添加普通的 JavaScript 文件以前先轉換部分文件的場景頗有用,添加新的文件後能夠對全部文件統一進行壓縮並混淆(uglifying)。promise
dest() 能夠用在管道(pipeline)中間用於將文件的中間狀態寫入文件系統。當接收到一個文件時,當前狀態的文件將被寫入文件系統,文件路徑也將被修改以反映輸出文件的新位置,而後該文件繼續沿着管道(pipeline)傳輸。 此功能可用於在同一個管道(pipeline)中建立未壓縮(unminified)和已壓縮(minified)的文件。bash
const { src, dest } = require('gulp');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
exports.default = function() {
return src('src/*.js')
.pipe(babel())
.pipe(src('vendor/*.js'))
.pipe(dest('output/'))
.pipe(uglify())
.pipe(rename({ extname: '.min.js' }))
.pipe(dest('output/'));
}
複製代碼
src() 能夠工做在三種模式下:緩衝(buffering)、流動(streaming)和空(empty)模式。這些模式能夠經過對 src() 的 buffer 和 read 參數 進行設置。babel
緩衝(Buffering)模式是默認模式,將文件內容加載內存中。插件一般運行在緩衝(buffering)模式下,而且許多插件不支持流動(streaming)模式。併發
流動(Streaming)模式的存在主要用於操做沒法放入內存中的大文件,例如巨幅圖像或電影。文件內容從文件系統中以小塊的方式流式傳輸,而不是一次性所有加載。若是須要流動(streaming)模式,請查找支持此模式的插件或本身編寫。
空(Empty)模式不包含任何內容,僅在處理文件元數據時有用。
glob 是由普通字符和/或通配字符組成的字符串,用於匹配文件路徑。能夠利用一個或多個 glob 在文件系統中定位文件。
Gulp 插件實質上是 Node 轉換流(Transform Streams),它封裝了經過管道(pipeline)轉換文件的常見功能,一般是使用 .pipe() 方法並放在 src() 和 dest() 之間。他們能夠更改通過流(stream)的每一個文件的文件名、元數據或文件內容。
const { src, dest } = require('gulp');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
exports.default = function() {
return src('src/*.js')
// gulp-uglify 插件並不改變文件名
.pipe(uglify())
// 所以使用 gulp-rename 插件修改文件的擴展名
.pipe(rename({ extname: '.min.js' }))
.pipe(dest('output/'));
}
複製代碼
gulp api 中的 watch() 方法利用文件系統的監控程序(file system watcher)將 globs 與 任務(task) 進行關聯。它對匹配 glob 的文件進行監控,若是有文件被修改了就執行關聯的任務(task)。若是被執行的任務(task)沒有觸發 異步完成 信號,它將永遠不會再次運行了
const { watch, series } = require('gulp');
function clean(cb) {
// body omitted
cb();
}
function javascript(cb) {
// body omitted
cb();
}
function css(cb) {
// body omitted
cb();
}
// 能夠只關聯一個任務
watch('src/*.css', css);
// 或者關聯一個任務組合
watch('src/*.js', series(clean, javascript));
複製代碼
# Babel 7
$ npm install --save-dev gulp-babel @babel/core @babel/preset-env
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.task('default', () =>
gulp.src('src/app.js')
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(gulp.dest('dist'))
);
複製代碼