启用其他地方的 gulpfile

var gulp = require('gulp');
var path = require('path');

try {
    require(path.resolve(__dirname, gulp.env.gulpfile));
} catch(err) {
    console.error('Unable to load %s', gulp.env.gulpfile);
}

在一个任务中处理多个

// npm install gulp event-stream

var gulp = require('gulp');
var es = require('event-stream');

gulp.task('test', function(cb) {
    return es.concat(
        gulp.src('bootstrap/js/*.js')
            .pipe(gulp.dest('public/bootstrap')),
        gulp.src('jquery.cookie/jquery.cookie.js')
            .pipe(gulp.dest('public/jquery'))
    );
});

如何在命令行中传递参数

好处: DRY

gulpfile.js

var gulp = require('gulp');
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');

var isProduction = gulp.env.type === 'production';

gulp.task('scripts', function(){
    return gulp.src('**/*.js')
        .pipe(gulpif(isProduction, uglify()))
        .pipe(gulp.dest('dist'));
});

在命令行中传递参数:

gulp scripts --type production

这个任务的目的只在产品化的构建中启用 .js 文件压缩。

指定新的 cwd (current working directory)

有利于使用嵌套的目录结构,比如:

/project
    /layer1
    /layer2

可以使用 gulp CLI 选项 --cwd 来修改当前工作目录。

比如在 project 目录执行以下操作:

gulp --cwd ./layer1/

也可以使用 process.chdir 选项来处理这个操作,这只是一个普通的 Node 操作。

gulpfile.js

var gulp = require('gulp');

try {
    process.chdir(gulp.env.cwd);
} catch(err) {
    console.error('Unable to chdir to %s', gulp.env.cwd);
}

如果只需要针对一个确定的 glob 指定 cwd,那么在 glob-stream 上使用 cwd 选项就可以了。

gulp.src('../some/dir/**/*.js', {cwd: './public'});

文件变化时构建

依赖于官方的 gulp-watch

var gulp = require('gulp');
var sass = require('gulp-sass');
var watch = require('gulp-watch');

gulp.task('default', function() {
    return gulp.src('sass/*.scss')
        .pipe(watch())
        .pipe(sass())
        .pipe(gulp.dest('dest/css'));
});

组合流(streams)用以处理错误

默认情况下,在流中触发错误会导致抛出异常,除非已经给其 error 事件上附加了给定的监听器。但是这样在使用管道流的时候就变得有点棘手了。

通过gulp-util的 combine 方法可以将多个流合并为一个流,这就意味着只需要在代码特定某一个地方监听 error 事件就行了。

下面是一个在 gulpfile 中使用合并流的例子:

var combine = require('gulp-util').combine;
var uglify = require('uglify');
var gulp = require('gulp');

gulp.task('test', function() {
    var combined = combine(
        gulp.src('bootstrap/js/*.js'),
        uglify(),
        gulp.dest('public/boostrap')
    );
    
    // 前面所有任务的错误都会在下面的代码中捕获,而不会抛出异常
    combined.on('error', function(err) {
        console.warn(err.message);
    });
    
    return combined;
});

也可以在 gulp 插件和 node 以及使用 multipipe 模块的过程中使用这个技术,这个非常有用,也意味着可以确保错误不会在人际罕见的 ./node_modules 中排除错误。

运行多个任务

默认情况下,会最大限度的并发运行任务 -- 例如一次启动所有的任务而不需要等待什么。如果希望创建一系列的任务然后按照指定的顺序运行,需要做以下两件事:

  • 给任务相应的提示信息来告诉它什么时候任务运行完成,
  • 然后给任务想听的提示,任务依赖于其他任务完成。

举个例子,结舌我们有两个任务,'one' 和 'two',然后希望按照下面执行的允许运行:

  1. 在任务 'one' 里面添加一个提示告诉任务它什么时候完成。无论是给它一个回调函数在任务完成的时候调用还是返回一个 promise 或者流,引擎应该等待解决它或者分别完成。
  2. 在任务 'two' 中添加一个提示,然后告诉引擎它依赖于第一个任务完成。

看起来像下面这个例子:

var gulp = require('gulp');

// 传递一个回调函数,因此引擎就会知道这个任务什么时候完成
gulp.task('one', function(cb) {
    // 做些事情 -- 异步或者其他方式
    cb(err); // 如果错误不是 null 或者是 undefined,那么业务流程就会终止,而任务 'two' 不会运行
    
});

// 在这个任务开始执行之前确定某些任务必须完成了
gulp.task('two', ['one'], function() {
    // 任务 'one' 现在已经完成了
});

gulp.task('default', ['one', 'two']);
// 或者是: gulp.task('default', ['two']);