gulp实用教程

本文针对有一定前端工程化的同学阅读,在开始学习之前请确认安装好了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的内容也就这么多了,日后在工作中继续总结,希望大家看完有所收获。

你可能感兴趣的:(gulp实用教程)