AJax技术

Gulp高级技巧

字号+ 作者:H5之家 来源:H5之家 2015-11-18 09:40 我要评论( )

Gulp思维 —— Gulp高级技巧 2015-11-16 23:08 | 45人阅读 | 来源 感受过gulp.js带来的兴奋过后,你需要的不仅仅是它的光鲜,而是切切实实的实例。这篇文章讨论了一些使用gulp.js时常踩的坑,以及一些更加高级和定制化的插件和流的使用技巧。 基本任务 gulp

Gulp思维 —— Gulp高级技巧

2015-11-16 23:08 | 45人阅读 | 来源

感受过gulp.js带来的兴奋过后,你需要的不仅仅是它的光鲜,而是切切实实的实例。这篇文章讨论了一些使用gulp.js时常踩的坑,以及一些更加高级和定制化的插件和流的使用技巧。

基本任务

gulp的基本设置拥有非常友好的语法,让你能够非常方便的对文件进行转换:

gulp.task('scripts', function() { return gulp.src('./src/**/*.js') .pipe(uglify()) .pipe(concat('all.min.js')) .pipe(gulp.dest('build/')); });

这种方式能够应付绝大多数情况,但如果你需要更多的定制,很快就会遇到麻烦了。这篇将介绍这其中的一些情况并提供解决方案。

流不兼容?

使用gulp时,你可能会陷入“流不兼容”的问题。这主要是因为常规流和Vinyl文件对象有差异,或是使用了仅支持buffer(不支持流)库的gulp插件与常规流不兼容。

比如说,你不能直接将常规流与gulp和(或)gulp插件相连。我们创建一个可读流,并尝试使用gulp-uglify和gulp-rename来进行转换,将最后得到的内容交给gulp.dest()。下面就是个错误的例子:

var uglify = require('gulp-uglify'), rename = require('gulp-rename'); gulp.task('bundle', function() { return fs.createReadStream('app.js') .pipe(uglify()) .pipe(rename('bundle.min.js')) .pipe(gulp.dest('dist/')); });

为什么我们不能将可读流和一个gulp插件直接相连?gulp难道不就是一个基于流的构建系统吗?是的,但上面的例子忽视了一个事实,gulp插件期望的输入是Vinyl文件对象。你不能直接将一个可读流与一个以Vinyl文件对象作为输入的函数(插件)相连

Vinyl文件对象

gulp使用了vinyl-fs,它实现了gulp.src()和gulp.dest()方法。vinyl-fs使用vinyl文件对象——一种“虚拟文件格式”。如果我们需要将gulp和(或)gulp插件与常规的可读流一起使用,我们就需要先把可读流转换为vinyl。

使用vinyl-source-stream是个不错的选择,如下:

var source = require('vinyl-source-stream'), marked = require('gulp-marked'); fs.createReadStream('*.md') .pipe(source()) .pipe(marked()) .pipe(gulp.dest('dist/'));

另外一个例子首先通过browserify封装并最终将其转换为一个vinyl流:

var browserify = require('browserify'), uglify = require('gulp-uglify'), source = require('vinyl-source-stream'); gulp.task('bundle', function() { return browserify('./src/app.js') .bundle() .pipe(source(‘bundle.min.js)) .pipe(uglify()) .pipe(gulp.dest('dist/')); });

哎呦不错哦。注意我们不再需要使用gulp-rename了,因为vinyl-source-stream创建了一个拥有指定文件名的vinyl文件实例(这样gulp.dest方法将使用这个文件名)

gulp.dest

这个gulp方法创建了一个可写流,它真的很方便。它重新使用可读流中的文件名,然后在必要时创建文件夹(使用mkdirp)。在写入操作完成后,你能够继续使用这个流(比如:你需要使用gzip压缩数据并写入到其他文件)

流和buffer

既然你有兴趣使用gulp,这篇文章假设你已经了解了流的基础知识。无论是buffer还是流,vinyl的虚拟文件都能包含在内。使用常规可读流时,你可以监听data事件来检测数据碎片的到来:

fs.createReadStream('/usr/share/dict/words').on('data', function(chunk) { console.log('Read %d bytes of data', chunk.length); }); > Read 65536 bytes of data > Read 65536 bytes of data > Read 65536 bytes of data > Read 65536 bytes of data > ...

不同的是,使用gulp.src()会将转换成buffer的vinyl文件对象重新写入到流中。也就是说,你获得的不再是数据碎片,而是将内容转换成buffer后的(虚拟)文件。vinyl文件格式拥有一个属性来表示里面是buffer还是流,gulp默认使用buffer:

gulp.src('/usr/share/dict/words').on('data', function(file) { console.log('Read %d bytes of data', file.contents.length); }); > Read 2493109 bytes of data

这个例子说明了在文件被完整加入到流之前数据会被转换成buffer。

Gulp默认使用buffer

尽管更加推荐使用流中的数据,但很多插件的底层库使用的是buffer。有时候必须使用buffer,因为转换需要完整的文件内容。比如文本替换和正则表达式的情形。如果使用数据碎片,将会面临匹配失败的风险。同样,像UglifyJS和Traceur Compiler需要输入完整的文件内容(至少需要语法完整的JavaScript字符串)

这就是为什么gulp默认使用转换成buffer的流,因为这更好处理。

使用转换成buffer的流也有缺点,处理大文件时将非常低效。文件必须完全读取,然后才能被加入到流中。那么问题来了,文件的尺寸多大才会降低性能?对于普通的文本文件,比如JavaScript、CSS、模板等等,这些使用buffer开销非常小。

在任何情况下,如果将buffer选项设为false,你可以告诉gulp流中传递的内容究竟是什么。如下所示:

gulp.src('/usr/share/dict/words', {buffer: false}).on('data', function(file) { var stream = file.contents; stream.on('data', function(chunk) { console.log('Read %d bytes of data', chunk.length); }); }); > Read 65536 bytes of data > Read 65536 bytes of data > Read 65536 bytes of data > Read 65536 bytes of data > ... 从流到buffer

由于所需的输入(输出)流和gulp插件不尽相同,你可能需要将流转换成buffer(反之亦然)。之前已经有过介绍,大多数插件使用buffer(尽管他们的一部分也支持流)。比如gulp-uglify和gulp-traceur。你可以通过gulp-buffer来转换成buffer:

var source = require('vinyl-source-stream'), buffer = require('gulp-buffer'), uglify = require('gulp-uglify'); fs.createReadStream('./src/app.js') .pipe(source('app.min.js')) .pipe(buffer()) .pipe(uglify()) .pipe(gulp.dest('dist/'));

或者另一个例子:

var buffer = require('gulp-buffer'), traceur = require('gulp-traceur'); gulp.src('app.js', {buffer: false}) .pipe(buffer()) .pipe(traceur()) .pipe(gulp.dest('dist/')); 将buffer转换为流

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 网页注册表单的网页设计技巧

    网页注册表单的网页设计技巧

    2016-02-06 16:00

  • ajax技巧制作得在线歌词搜索功效

    ajax技巧制作得在线歌词搜索功效

    2016-02-06 14:47

  • 今天开始应该使用 5 个JavaScript调试技巧

    今天开始应该使用 5 个JavaScript调试技巧

    2016-01-23 17:00

  • asp.net开发常用技巧收集(2)

    asp.net开发常用技巧收集(2)

    2016-01-23 16:01

网友点评
r