const gulp = require('gulp');
gulp.task('default', function() {
gulp.src('js/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist'));
});
复制代码
注意:默认的,task 将以最大的并发数执行,gulp 会一次性运行全部的 task 而且不作任何等待。若是你想要建立一个序列化的 task 队列,并以特定的顺序执行,你须要作两件事:node
var gulp = require('gulp');
// 返回一个 callback,所以系统能够知道它何时完成
gulp.task('one', function(cb) {
// 作一些事 -- 异步的或者其余的
cb(err); // 若是 err 不是 null 或 undefined,则会中止执行,且注意,这样表明执行失败了
这里也可使用 return 代替 cb()
});
// 定义一个所依赖的 task 必须在这个 task 执行以前完成
gulp.task('two', ['one'], function() {
// 'one' 完成后
});
gulp.task('default', ['one', 'two']);
复制代码
我的认为了解 gulp 的核心知识,主要从三个方面来了解:git
上面三点分别对应了gulp的 pipe(这样写不太严谨,由于pipe是流的api),src和task 这三个API,了解了这三部分,gulp的使用,插件的编写都会比较驾轻就熟。github
说实话到如今也没有对流的全部知识十分了解,以前查阅了一些 node 相关的书,感受不少书写的东西和例子都很浅,后来看了一些文章,算是了解了一点皮毛。这是网传的学习流必看的文章,有兴趣的能够看看。gulp
本文默认读者对流有了必定的了解,所以这里对流的种类,相关API和使用不会说的很详细。并发
stream不会占用大量内存。例如 fs.readFile 在读取文件时,会把整个文件读取到内存当中,当文件很大时,会很占用内存,甚至会超出v8的内存限制,致使程序退出。流则是读一部分,写一部分,并且可以充分地利用 Buffer 不受 V8 内存控制的特色,利用堆外内存完成高效地传输。异步
gulp 内部使用了 through2 封装好的 transform 流(后面会展开说),这一步是在 gulp.src 的时候完成的,所以咱们能够看到这样的代码:函数
gulp.src(xxx).pipe(xxx)...
复制代码
我我的理解的 pipe 就是一根水管,左边是可读流(readStream),右边是可写流(writeStream)。正由于 gulp 帮咱们封装好了流,所以,咱们能够直接使用 pipe 这个 api 来传输数据。oop
学习插件的编写能让咱们对gulp中流的使用有更深刻的认识,有的时候可能咱们须要一些定制话的功能来处理文件,这时就须要本身编写gulp的插件了,咱们先来看一个官方的例子:学习
var through = require('through2');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
// 常量
const PLUGIN_NAME = 'gulp-prefixer';
function prefixStream(prefixText) {
var stream = through();
stream.write(prefixText);
return stream;
}
// 插件级别函数 (处理文件)
function gulpPrefixer(prefixText) {
if (!prefixText) {
throw new PluginError(PLUGIN_NAME, 'Missing prefix text!');
}
prefixText = new Buffer(prefixText); // 预先分配
// 建立一个让每一个文件经过的 stream 通道
return through.obj(function(file, enc, cb) {
if (file.isNull()) {
// 返回空文件
cb(null, file);
}
if (file.isBuffer()) {
file.contents = Buffer.concat([prefixText, file.contents]);
}
if (file.isStream()) {
file.contents = file.contents.pipe(prefixStream(prefixText));
}
cb(null, file);
});
};
// 暴露(export)插件主函数
module.exports = gulpPrefixer;
复制代码
对于 gulp 插件的编写我认为这两点是比较重要的:
带着这些疑问,咱们先看下 through2 的源码:源码地址
// 前面的代码建立了一个 Transform 流,并给这个流添加了一个 destroy 方法
function through2 (construct) {
return function (options, transform, flush) {
if (typeof options == 'function') {
flush = transform
transform = options
options = {}
}
if (typeof transform != 'function')
transform = noop
if (typeof flush != 'function')
flush = null
return construct(options, transform, flush)
}
}
module.exports.obj = through2(function (options, transform, flush) {
var t2 = new DestroyableTransform(Object.assign({ objectMode: true, highWaterMark: 16 }, options))
t2._transform = transform
if (flush)
t2._flush = flush
return t2
})
复制代码
文件系统这个名字说着有点悬乎,其实这部分就是介绍一下 gulp.src 是怎么把文件加工成流的。
未完待续。。。