Gulp
是基于流的自動(dòng)化構(gòu)建工具骡苞,它不僅能對(duì)網(wǎng)站資源進(jìn)行優(yōu)化亚铁,而且在開發(fā)過程中能避免很多重復(fù)的工作捆探,比如對(duì)相關(guān)文件的操作助被,還有自動(dòng)監(jiān)視一些文件的變化等功能丰滑。
基本的常用API(gulp v3.X)
-
gulp.src(globs[, options])
輸出符合所提供的匹配模式或者匹配模式的數(shù)組的文件。 將返回一個(gè)stream文件流它可以被 piped 到別的插件中噩咪。
glob 相當(dāng)于文件的路徑,或者文件路徑數(shù)組灰伟。 gulp.dest(path[, options])
// 把上一步處理的數(shù)據(jù)輸出到指定的目錄path中,如果某文件夾不存在,將會(huì)自動(dòng)創(chuàng)建它。-
gulp.task(name[, deps], fn)
例子:
gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { // 做一些事 });
異步侄非、同步宛渐、規(guī)定執(zhí)行順序執(zhí)行任務(wù)
-
異步執(zhí)行任務(wù)
const gulp = require('gulp'); // 壓縮js代碼 gulp.task('js', function () { return gulp.src('src/js/*.js') // 匹配參數(shù)內(nèi)的文件寇蚊,并且將文件讀到gulp內(nèi)存中 .pipe(concat('bundle.js')) // 合并文件代碼 .pipe(gulp.dest('dist/js/')) // 輸出文件到指定目錄 .pipe(uglify()) // 壓縮當(dāng)前的js文件 .pipe(rename({ // 重命名文件 suffix: '.min' })) .pipe(gulp.dest('dist/js/')) })
// 壓縮css代碼 gulp.task('css', function () { return gulp.src('src/css/*.css') .pipe(concat('bundle.css')) .pipe(cleanCss()) // 壓縮css文件 .pipe(gulp.dest('dist/css/')) })
// 執(zhí)行數(shù)組內(nèi)的任務(wù) gulp.task('default', ['js', 'css'])
當(dāng)運(yùn)行命令 gulp
后,我們發(fā)現(xiàn)輸出的是
[11:31:43] Using gulpfile E:\練習(xí)\Gulp\4-12\gulpfile.js
[11:31:43] Starting 'css'...
[11:31:43] Starting 'js'...
[11:31:44] Finished 'js' after 72 ms
[11:31:44] Finished 'css' after 70 ms
[11:31:44] Finished 'default' after 33 μs
可以看到此時(shí)的任務(wù)是異步執(zhí)行的蚂蕴,應(yīng)用官方的一句話就是
默認(rèn)的朦蕴,task 將以最大的并發(fā)數(shù)執(zhí)行琴拧,也就是說除师,gulp 會(huì)一次性運(yùn)行所有的 task 并且不做任何等待锹安。
但是如果我們想要它同步執(zhí)行任務(wù)呢叹哭?應(yīng)該怎么做忍宋?看代碼
- 同步執(zhí)行任務(wù)
const gulp = require('gulp');
// 壓縮css代碼
gulp.task('css', function () {
gulp.src('src/css/*.css')
.pipe(concat('bundle.css'))
.pipe(cleanCss()) // 壓縮css文件
.pipe(gulp.dest('dist/css/'))
})
// 解析less代碼并且壓縮css代碼
gulp.task('less', function () {
gulp.src('src/less/*.less')
.pipe(concat('bundle_less.less'))
.pipe(less())
.pipe(cleanCss())
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest('dist/less'))
})
// 執(zhí)行數(shù)組內(nèi)的任務(wù)
gulp.task('default', ['js', 'css'], 'less')
輸出結(jié)果
[11:44:22] Using gulpfile E:\練習(xí)\Gulp\4-12\gulpfile.js
[11:44:22] Starting 'css'...
[11:44:22] Finished 'css' after 7.24 ms
[11:44:22] Starting 'less'...
[11:44:22] Finished 'less' after 3.01 ms
[11:44:22] Starting 'default'...
[11:44:22] Finished 'default' after 35 μs
可以看到超升,我們只需要把return
去掉即可實(shí)現(xiàn)同步進(jìn)行編譯輸出雹熬,也就是說挚赊,在task中只要不返回任何值即可實(shí)現(xiàn)同步執(zhí)行任務(wù)
如果想特定安排任務(wù)的執(zhí)行順序呢?(同步異步都執(zhí)行)
- 按規(guī)定順序執(zhí)行任務(wù)
const gulp = require('gulp');
// 返回一個(gè) callback柬帕,因此系統(tǒng)可以知道它什么時(shí)候完成
gulp.task('one', function(cb) {
// 做一些事 -- 異步的或者其他的
cb(err); // 如果 err 不是 null 或 undefined哟忍,則會(huì)停止執(zhí)行狡门,且注意,這樣代表執(zhí)行失敗了
});
// 定義一個(gè)所依賴的 task 必須在這個(gè) task 執(zhí)行之前完成
gulp.task('two', ['one'], function() {
// 'one' 完成后
});
gulp.task('default', ['one', 'two']);
解析:運(yùn)行時(shí)锅很,gulp會(huì)執(zhí)行task one
其馏,當(dāng)執(zhí)行該函數(shù)的回調(diào)時(shí)候,如果 err 不是 null 或 undefined粗蔚,則會(huì)停止執(zhí)行尝偎,且注意,這樣代表執(zhí)行失敗了鹏控,如果沒有發(fā)生錯(cuò)誤致扯,那么才回去執(zhí)行task two
。也就是說当辐,任務(wù)two
必須在任務(wù)one
的后面執(zhí)行
了解常用插件
-
gulp-concat
合并文件抖僵,減少網(wǎng)絡(luò)請(qǐng)求≡稻荆基本使用方法:const gulp = require('gulp'), concat = require('gulp-concat'), pump = require('pump'); gulp.task('testConcat', function (cb) { pump([ gulp.src('src/js/*.js'), concat('all.js'),//合并后的文件名 gulp.dest('dist/js') ], cb); });
-
gulp-uglify
壓縮js文件,減少文件體積,去掉沒有引用的代碼耍群。基本使用方法:gulp.task('jsmin',function(){ gulp.src(['src/js/index.js','src/js/detail.js'])//多個(gè)文件以數(shù)組形式傳入 .pipe(uglify({ //mangle: true,//類型:Boolean 默認(rèn):true 是否修改變量名 mangle:{except:['require','exports','module','$']},//排除混淆關(guān)鍵字 compress:true,//類型:Boolean 默認(rèn):true 是否完全壓縮 preserveComments:'all'//保留所有注釋 })) .pipe(gulp.dest('dist/js')) });
-
gulp-rename
修改文件名找筝,例如將demo.css修改為demo.min.css蹈垢,一般配合gulp-minify-css/gulp-uglify壓縮插件一起使用⌒湓#基本使用方法(修改輸出的js文件名):gulp.task('renamejs',function(){ return pump([ gulp.src('src/js/*.js'), rename({suffix: '.min'}), // 輸出文件名修改為帶.min的文件名 uglify(), gulp.dest('dist/js') ]) })
-
gulp-clean-css
使用gulp-clean-css壓縮css文件曹抬,減小文件大小,并給引用url添加版本號(hào)避免緩存急鳄。(之前的有同樣功能的gulp-minify-css已被廢棄)谤民。基本使用方法:gulp.task('testCssmin', function () { gulp.src('src/css/*.css') .pipe(cssmin({ advanced: false, //類型:Boolean 默認(rèn):true [是否開啟高級(jí)優(yōu)化(合并選擇器等)] compatibility: 'ie7', //保留ie7及以下兼容寫法 類型:String 默認(rèn):''or'*' [啟用兼容模式疾宏; 'ie7':IE7兼容模式张足,'ie8':IE8兼容模式,'*':IE9+兼容模式] keepBreaks: true, //類型:Boolean 默認(rèn):false [是否保留換行] keepSpecialComments: '*' //保留所有特殊前綴 當(dāng)你用autoprefixer生成的瀏覽器前綴坎藐,如果不加這個(gè)參數(shù)为牍,有可能將會(huì)刪除你的部分前綴 })) .pipe(gulp.dest('dist/css')); });
-
gulp-less
使用gulp-less插件將less文件編譯成css,當(dāng)有l(wèi)ess文件發(fā)生改變自動(dòng)編譯less岩馍,并保證less語法錯(cuò)誤或出現(xiàn)異常時(shí)能正常工作并提示錯(cuò)誤信息碉咆。基本使用方法:gulp.task('testLess', function () { gulp.src('src/less/index.less') .pipe(less()) // 解析less文件轉(zhuǎn)換為css .pipe(gulp.dest('src/css')); });
-
gulp-htmlmin
使用gulp-htmlmin壓縮html兼雄,可以壓縮頁面javascript吟逝、css帽蝶,去除頁面空格赦肋、注釋块攒,刪除多余屬性等操作〉璩耍基本使用方法:const htmlMin = require('gulp-htmlmin'); gulp.task('testHtmlmin', function () { gulp.src('src/html/*.html') .pipe(htmlMin({ removeComments: true,//清除HTML注釋 collapseWhitespace: true,//壓縮HTML collapseBooleanAttributes: true,//省略布爾屬性的值 <input checked="true"/> ==> <input /> removeEmptyAttributes: true,//刪除所有空格作屬性值 <input id="" /> ==> <input /> removeScriptTypeAttributes: true,//刪除<script>的type="text/javascript" removeStyleLinkTypeAttributes: true,//刪除<style>和<link>的type="text/css" minifyJS: true,//壓縮頁面JS minifyCSS: true//壓縮頁面CSS })) // 解析html文件并且壓縮 .pipe(gulp.dest('dist/html')); });
-
gulp-livereload
實(shí)現(xiàn)項(xiàng)目自動(dòng)編譯(半自動(dòng)囱井,頁面不會(huì)刷新)∪け埽基本使用方法:const livereload = require('gulp-livereload'); gulp.task('testLess', function () { gulp.src('src/less/index.less') .pipe(less()) // 解析less文件轉(zhuǎn)換為css .pipe(gulp.dest('src/css')) .pipe(livereload()) }); // 這里要先讓默認(rèn)任務(wù)執(zhí)行一遍后 gulp.task('watch', ['default'], function () { // 開啟監(jiān)聽 livereload.listen(); // 確認(rèn)監(jiān)聽的目標(biāo)文件和對(duì)應(yīng)所執(zhí)行的task gulp.watch('src/less/*.less', ['testLess']); gulp.watch('src/html/*.html', ['minHtml']); })
-
gulp-connect
實(shí)現(xiàn)實(shí)時(shí)編譯和瀏覽器自動(dòng)刷新(全自動(dòng))庞呕。基本使用方法:const connect = require('gulp-connect'); gulp.task('css', function () { return pump([ gulp.src('src/css/*.css'), concat('bundle.css'), cleanCss(), rename({ suffix: '.min' }), gulp.dest('dist/css/'), connect.reload() // 這一句實(shí)現(xiàn)修改后會(huì)刷新 ]) }) gulp.task('server', ['default'], function () { connect.server({ root: 'dist/', // 編譯后對(duì)應(yīng)映射到哪個(gè)文件目錄下 port: 8080, // 端口號(hào) livereload: true // 使用自動(dòng)編譯 }); gulp.watch('src/css/*.css', ['css']); gulp.watch('src/html/*.html', ['minHtml']); })
-
gulp-autoprefixer
實(shí)現(xiàn)版本自動(dòng)添加前綴程帕∽×罚基本使用方法:const autoprefixer = require('gulp-autoprefixer') /*自動(dòng)加前綴*/ gulp.task('autoprefixer', function () { return gulp.src('css/*.css') .pipe(autoprefixer({ browsers: ["last 2 versions","Firefox >= 20"], /*last 2 versions: 主流瀏覽器的最新兩個(gè)版本 ● last 1 Chrome versions: 谷歌瀏覽器的最新版本 ● last 2 Explorer versions: IE的最新兩個(gè)版本 ● last 3 Safari versions: 蘋果瀏覽器最新三個(gè)版本 ● Firefox >= 20: 火狐瀏覽器的版本大于或等于20 ● iOS 7: IOS7版本 ● Firefox ESR: 最新ESR版本的火狐 ● > 5%: 全球統(tǒng)計(jì)有超過5%的使用率 */ cascade: true, //是否美化屬性值 默認(rèn):true 像這樣: //-webkit-trans==>m: rotate(45deg); // trans==>m: rotate(45deg); remove:true //是否去掉不必要的前綴 默認(rèn):true })) .pipe(gulp.dest('css/')); });
-
gulp-load-plugins
所有的gulp插件都存在這里面〕钍茫基本使用方法:// 必須要先調(diào)用一下這個(gè)函數(shù)才能使用 const $ = require('gulp-load-plugins')(); // 此時(shí), 這些不在需要引入 const concat = require('gulp-concat'); const uglify = require('gulp-uglify'); const rename = require('gulp-rename'); const cleanCss = require('gulp-clean-css'); ... // 使用下面的寫法代替上面的插件 $.concat $.uglify $.rename $.cleanCss $.htmlmin ...
-
gulp-babel
編譯ES6讲逛、7轉(zhuǎn)換為ES5×氩海基本使用方法:const babel = require('gulp-babel'); gulp.task('es', function () { return gulp.src('src/js_es6/*.js') .pipe(babel({ // 編譯es6語法 presets: ["@babel/env"], plugins: [] })) .pipe(concat('bundle.js')) .pipe(gulp.dest('dist/')) }) gulp.task('default', gulp.series(['es'])) // 依賴版本 // "@babel/core": "^7.4.3", // "@babel/preset-env": "^7.4.3", // "gulp": "^4.0.0", // "gulp-babel": "^8.0.0",
Gulp4.0升級(jí)了什么
-
gulp
在gulp.task()
中移除了三參數(shù)語法盏混,現(xiàn)在不能使用數(shù)組來指定一個(gè)任務(wù)的依賴。gulp 4.0 加入了 gulp.series 和 gulp.parallel 來實(shí)現(xiàn)任務(wù)的串行化和并行化惜论。gulp.series 用于串行(順序)執(zhí)行
gulp.task('default', gulp.series(['html', 'css', 'js']))
gulp.parallel 用于并行執(zhí)行,如果你想并行執(zhí)行scripts和styles许赃,你可以這么寫:
gulp.task('default', gulp.parallel('scripts', 'styles'));
通常gulp.series 和 gulp.parallel我們需要配合來使用。
-
依賴陷阱
讓我們看一下這個(gè)Gulp3的例子:
// default任務(wù)馆类,需要依賴scripts和styles gulp.task('default', ['scripts', 'styles'], function() {}); // script和styles任務(wù)都依賴clean gulp.task('styles', ['clean'], function() {}); gulp.task('scripts', ['clean'], function() {}); // clean任務(wù)用來清空目錄 gulp.task('clean', function() {});
當(dāng)Gulp開始工作混聊,它會(huì)創(chuàng)建一個(gè)任務(wù)依賴樹
它發(fā)現(xiàn)clean任務(wù)是另外兩個(gè)task的依賴,從而確保clean只執(zhí)行一次蹦掐。
但遺憾的是技羔,我們?cè)谛掳姹局袑]辦法運(yùn)用這個(gè)特性。如果你在遷移到Gulp4的過程中只像下面的例子一樣做了簡單的改變卧抗,clean任務(wù)將會(huì)被執(zhí)行兩次:
// 任務(wù)直接不再有依賴 gulp.task('styles', function() {...}); gulp.task('scripts', function() {...}); gulp.task('clean', function() {...}); // default任務(wù)藤滥,需要依賴scripts和styles gulp.task('default', gulp.series('clean', gulp.parallel('scripts', 'styles')));
-
異步任務(wù)支持
如果你執(zhí)行的是同步任務(wù),在Gulp3中不需要寫任何其他代碼社裆,但是在Gulp4中就不能如此輕松了:現(xiàn)在也你必須運(yùn)行done回調(diào)(這可能是我最早發(fā)現(xiàn)的一個(gè)變化)拙绊。然后如果你執(zhí)行的是異步任務(wù),你則有三個(gè)選擇來確保Gulp能夠檢測到你的任務(wù)真的完成了:
- 回調(diào)
const del = require('del'); // del 模塊用來刪除指定目錄的文件 gulp.task('clean', function(done) { del(['.build/'], done); });
- 流
返回一個(gè)流告訴gulp任務(wù)你已經(jīng)處理完成gulp.task('somename', function() { return gulp.src('client/**/*.js') .pipe(minify()) .pipe(gulp.dest('build')); });
- Promise
返回一個(gè)Promise來告訴gulp任務(wù)已經(jīng)處理完成var promisedDel = require('promised-del'); gulp.task('clean', function() { return promisedDel(['.build/']); });
-
使用函數(shù)定義任務(wù)
具體使用方法:
// 只需要在`series` 和 `parallel` 中間引用函數(shù)名就能組成一個(gè)新任務(wù) gulp.task('default', gulp.series(clean, gulp.parallel(scripts, styles))); // 把單個(gè)任務(wù)變成一個(gè)函數(shù) function styles() {} function scripts() {} function clean() {}
此處參考了:
【譯】相對(duì)完整的Gulp4升級(jí)指南
Gulp 4: gulp.parallel gulp.series -- 全新的任務(wù)執(zhí)行體系