本文针对有一定前端工程化的同学阅读,在开始学习之前请确认安装好了gulp。
我们首先在项目目录下新建一个gulpfile.js文件
//导入工具包 require('node_modules里对应模块')
var gulp = require('gulp'),
less = require('gulp-less'),
uglify = require('gulp-uglify');
//定义一个testLess任务(自定义任务名称)
gulp.task('testLess', function () {
gulp.src('src/less/index.less') //该任务针对的文件
.pipe(less()) //该任务调用的模块
.pipe(gulp.dest('src/css')); //将会在src/css下生成index.css
});
//定义另外一个任务,压缩js
gulp.task('jsmin', function () {
gulp.src(['src/js/index.js','src/js/detail.js']) //多个文件以数组形式传入
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
gulp.task('default',['testLess', 'jsmin']);
在命令行中,输入gulp就会执行上面2个任务,说明一点运行gulp相当于运行gulp default
gulp.task('default',['testLess', 'jsmin'],callback);
其实后面还可以跟一个回调函数 callback,当任务执行完后会调用。
如果现在我有一个js文件夹,下面又有一个或者几个子文件夹,我想把下面所有的js文件dest到另外一个文件夹下,该如何做。
gulp.task('jsmin', function () {
gulp.src('src/js/**/*.js',) //注意这种写法,js目录下及其子目录下的文件
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
匹配 src/js/qwe/aa.js
写入 dist/js/qwe/aa.js 会在目的地文件夹下自动创建子文件夹
现在的需求是我们需要忽略该目录下的2个js文件,c.js和 d.js,不让他去目的地,该如何做呢。
gulp.task('jsmin', function () {
//除了c.js和d.js(**匹配src/js的0个或多个子文件夹)
gulp.src(['src/js/**/*.js','!src/js/**/{c,d}.js'])
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
我们再来看一个比较奇葩的写法
gulp.src('./client/templates/*.jade')
.pipe(jade())
.pipe(gulp.dest('./build/templates'))
.pipe(minify())
.pipe(gulp.dest('./build/minified_templates'));
上面2种写法,分别是把./client/templates/*.jade转化成html存到./build/templates下面,后面一个转成html后压缩到另外一个目录。
var concat = require('gulp-concat');
gulp.task('scripts', function() {
return gulp.src(['./lib/file3.js', './lib/file1.js', './lib/file2.js'])
.pipe(concat('all.js'))
.pipe(gulp.dest('./dist/'));
});
gulp-concat可以把文件合并,上面是把'./lib/file3.js' 等3个文件合并成名为all.js的文件放到dist目录下。
在gulp中有一个很强大的功能,就是监视文件变化便作出反应。
var gulp = require('gulp'),
less = require('gulp-less');
gulp.task('testLess', function () {
gulp.src(['src/less/index.less','src/less/detail.less']) //多个文件以数组形式传入
.pipe(less())
.pipe(gulp.dest('src/css')); //将会在src/css下生成index.css以及detail.css
});
gulp.task('reload',function(){
任务代码
})
var watcher = gulp.watch('js/**/*.js', ['testLess','reload']);
//比如此时我们改动了js/test/aa.js,会触发下面这个事件
watcher.on('change',function(event){
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
})
当js文件夹下所有文件发生变化时,会有2个任务会去执行,一个是把2个less文件转成css文件放到src/css目录下,还有一个任务是reload,具体代码没写。。。
gulp.watch返回一个watcher,它总会返回一个 EventEmitter 来发射(emit) change 事件。
gulp.task('watch', function() {
// Watch .scss files
gulp.watch('src/styles/**/*.scss', ['styles']);
// Watch .js files
gulp.watch('src/scripts/**/*.js', ['scripts']);
// Watch image files
gulp.watch('src/images/**/*', ['images']);
});
这种写法,定义一个watch任务实时监测,对应执行相印的任务。
当然gulp也可以做到,任何文件发生变化时,实时刷新页面。
var livereload = require('gulp-livereload'),
gulp.task('watch', function() {
// Create LiveReload server
livereload.listen();
// Watch any files in dist/, reload on change
gulp.watch(['dist/**']).on('change', livereload.changed);
});
因为我们的文件都是dest到dist目录下,所以只要该文件下有任何变化,都会作出反应。
下面给出一段gulp工程的通用代码
var autoprefixer = require('gulp-autoprefixer'),
gulp.task('styles', function() {
return gulp.src('src/styles/main.scss')
.pipe(sass({ style: 'expanded' }))
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe(gulp.dest('dist/assets/css'))
.pipe(rename({suffix: '.min'}))
.pipe(minifycss())
.pipe(gulp.dest('dist/assets/css'))
.pipe(notify({ message: 'Styles task complete' }));
});
上面这个这个任务解决了我们在写css不用手动加前缀的问题。
var gulp = require('gulp');
var del = require('del');
gulp.task('clean:mobile', function (cb) {
del([
'dist/report.csv',
// 这里我们使用一个通配模式来匹配 `mobile` 文件夹中的所有东西
'dist/mobile/**/*',
// 我们不希望删掉这个文件,所以我们取反这个匹配模式
'!dist/mobile/deploy.json'
], cb);
});
gulp.task('default', ['clean:mobile']);
有时我们想要执行任务清除一些文件,便会用到del插件。
一个gulp的task只能返回一个stream,但有的时候有这么一种情景:有两类文件,它们的原始位置和处理后的位置都是不同的,但它们的处理流程相同。由于gulp.src和gulp.dest的参数不同,我们就需要写两个task来分别完成这个任务,一方面略显重复,另一方面逻辑上来讲这两个task本来就是处理同样的事情的。这种情况就需要merge-stream登场了,它的作用就是将2个stream合成一个返回。比如下面这个例子:
var merge = require('merge-stream');
gulp.task('jade', function () {
var stream1 = jade(src1, dest1);
var stream2 = jade(src2, dest2);
return merge(stream1, stream2);
});
function jade (src, dest) {
return gulp
.src(src)
.pipe($.jade())
.pipe(gulp.dest(dest));
}
我写到这里的时候chrome居然又崩溃了,最后来个野路子吧。
这是一个统计文件大小变化的工具,通常与压缩类工具放在一起实用,比如
gulp.src('**/*.html')
.pipe($.bytediff.start())
.pipe($.minifyHtml({empty: true}))
.pipe($.bytediff.stop(bytediffFormatter))
.pipe(gulp.dest('dist'));
function bytediffFormatter (data) {
var difference = (data.savings > 0) ? ' smaller.' : ' larger.';
return data.fileName + ' went from ' +
(data.startSize / 1000).toFixed(2) + ' kB to ' +
(data.endSize / 1000).toFixed(2) + ' kB and is ' +
formatPercent(1 - data.percent, 2) + '%' + difference;
}
在压缩的pipe前后加上$.bytediff.start()和$.bytediff.stop(callback),即可统计压缩前后文件的变化。在callback中传入的参数data上,可以访问到很多变量,如文件名,变化前后的大小,变化百分比等等。
好了,关于gulp的内容也就这么多了,日后在工作中继续总结,希望大家看完有所收获。