gulp中的增量编译.doc

上传人:小** 文档编号:3008353 上传时间:2020-06-21 格式:DOC 页数:10 大小:54.02KB
返回 下载 相关 举报
gulp中的增量编译.doc_第1页
第1页 / 共10页
gulp中的增量编译.doc_第2页
第2页 / 共10页
点击查看更多>>
资源描述

《gulp中的增量编译.doc》由会员分享,可在线阅读,更多相关《gulp中的增量编译.doc(10页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、!-gulp 中的增量编译最近花一点时间学了下 gulp,顺便学了下 sass,因为工作中并不需要用(我比较希望学习是需求驱动),所以一直拖到现在才学。突然觉得学习这类工具性价比很高,半天一天即可上手,技能树丰富了(尽管可能只会 20%,但是可以完成 80% 的工作了啊!),简历丰富了,所以才有这么多 前端er 不屑数据结构和算法这些基础吧,毕竟投入产出比太低,学一个简单的算法的时间都够掌握两遍基本的 gulp 工作流了!言归正传,今天要讲的是 gulp 的增量编译。在编译的过程中,有没有发现很多不必要的编译呢?我们以如下的例子为例:复制代码let dest = css/;/ sass - c

2、ssgulp.task(css, function() / 任务名 return gulp.src(sass/*.scss) / 目标 sass 文件 .pipe(plumber(errorHandler: notify.onError(Error: ) .pipe(sass() / sass - css .pipe(debug(title: 编译) .pipe(gulp.dest(dest););gulp.task(watch, function() gulp.watch(sass/*.scss, css););gulp watch 启动监听,此时修改 sass 文件夹下的任意文件,都会编译

3、该文件夹下的所有文件,这不是我们希望的,我们希望只对修改过的文件进行编译,即增量编译(Incremental Builds)。gulp 官方推荐了 4 个用于增量编译的插件,我们一起来看看使用方法以及它们的差异。gulp-changed - only pass through changed filesgulp-cached - in-memory file cache, not for operation on sets of filesgulp-remember - pairs nicely with gulp-cachedgulp-newer - pass through newer s

4、ource files only, supports many:1 source:destgulp-changed首先推荐的是 gulp-changed,毕竟它的作者在 GitHub 上拥有 15k 的 followers。该插件默认是通过比较源文件和生成文件的修改时间来判断是否将文件往下传递(pipe 流),当然也可以通过 haschanged 改变默认比较方式,采用 sha1 比较,感觉有点像浏览器缓存中的 Last-Modified/If-Modified-Since 和 ETag/If-None-Match。个人觉得默认比较已经足够了。复制代码let dest = css/;/ sas

5、s - cssgulp.task(css, function() / 任务名 return gulp.src(sass/*.scss) / 目标 sass 文件 .pipe(plumber(errorHandler: notify.onError(Error: ) .pipe(changed(dest, / dest 参数需要和 gulp.dest 中的参数保持一致 extension: .css / 如果源文件和生成文件的后缀不同,这一行不能忘 ) / sass() will only get the files that / changed since the last time it w

6、as run .pipe(sass() / sass - css .pipe(debug(title: 编译) .pipe(gulp.dest(dest);gulp.task(watch, function() gulp.watch(sass/*.scss, css););值得注意的是,如果源文件和生成文件的后缀不一样,需要加上 extension 参数。个人认为还有两点需要注意。第一点是因为 gulp-changed 是基于文件的判断,所以并不一定需要开启 watch(这和接下去要说的 gulp-cached 不同),怎么说?先用 gulp css 的命令编译一次,然后修改一个文件,再用 g

7、ulp css 编译一次,这样的操作是生效的。第二点,因为 gulp-changed 只会将修改过的文件往下 pipe,所以如果后续有需要合并的操作(concat 操作),那么就会导致文件缺失,合并后的文件其实就是修改过的文件了。所以 gulp-changed 只适合 1:1 的操作。gulp-cached和 gulp-changed 基于文件的对比不同,gulp-cached 可以将第一次传递给它的文件内容保留在内存中,如果之后再次执行 task,它会将传递给它的文件和内存中的文件进行比对,如果内容相同,就不再将该文件继续向后传递,从而做到了只对修改过的文件进行增量编译。复制代码let de

8、st = css/;/ sass - cssgulp.task(css, function() / 任务名 return gulp.src(sass/*.scss) / 目标 sass 文件 .pipe(plumber(errorHandler: notify.onError(Error: ) .pipe(cached(sass-task) / 取个名字 .pipe(sass() / sass - css .pipe(debug(title: 编译) .pipe(gulp.dest(dest);gulp.task(watch, function() gulp.watch(sass/*.scss

9、, css););和 gulp-changed 不同的是,gulp-cached 必须要开启 gulp watch,保证内存中存在副本,才能进行比较。gulp-remembergulp-remember 同样可以在内存中缓存所有曾经传递给它的文件,但是它和 gulp-cached 的区别是,在之后的 task 中,gulp-cached 会过滤掉未经修改的文件不再向下传递,而 gulp-remember 则会将未传递给它的文件进行补足从而能够继续向下传递,因此通过 gulp-cached 和 gulp-remember 的结合使用,既能做到只对修改过的文件进行编译,又能做到当相关联的文件任意一

10、个发生改变时,编译所有相关的文件。所以我觉得实际开发中用 gulp-cached+gulp-remember 的组合非常合适。复制代码let dest = css/;/ sass - cssgulp.task(css, function() / 任务名 return gulp.src(sass/*.scss) / 目标 sass 文件 .pipe(plumber(errorHandler: notify.onError(Error: ) .pipe(cached(sass-task) / 取个名字 .pipe(sass() / sass - css .pipe(debug(title: 编译)

11、 .pipe(gulp.dest(dest) .pipe(remember(sass-task) / 和 cached() 参数一致 .pipe(concat(all.css) .pipe(debug(title: 合并) .pipe(gulp.dest(dest);gulp.task(watch, function() gulp.watch(sass/*.scss, css););由于在第一次合并文件时,gulp-remember 已经将传递过来的文件缓存在内存中了,那么即使在后续的 task 执行中,gulp-cached 插件过滤掉了未经修改过的 css 文件,但是 gulp-remem

12、ber 还是能够通过自己的缓存来补全这些缺失的文件,从而做到正确地合并文件。我们还可以合理地管理两个插件的缓存,具体见文档。gulp-newergulp-newer 和 gulp-changed 类似,也是基于文件对比,不过它只支持最后修改时间的对比。1 : 1 进行增量编译的例子:复制代码let dest = css/;/ sass - cssgulp.task(css, function() / 任务名 return gulp.src(sass/*.scss) / 目标 sass 文件 .pipe(plumber(errorHandler: notify.onError(Error: )

13、.pipe(newer( dest: dest, ext: .css ) .pipe(sass() / sass - css .pipe(debug(title: 编译) .pipe(gulp.dest(dest);gulp.task(watch, function() gulp.watch(sass/*.scss, css););1 对 多进行增量编译的例子:复制代码let dest = css/;/ sass - cssgulp.task(css, function() / 任务名 return gulp.src(sass/*.scss) / 目标 sass 文件 .pipe(plumbe

14、r(errorHandler: notify.onError(Error: ) .pipe(newer(dest + all.css) .pipe(sass() .pipe(concat(all.css) .pipe(gulp.dest(dest););gulp.task(watch, function() gulp.watch(sass/*.scss, css););遗憾的是,貌似不能同时 1:1 & 1:多 进行编译(此处问号脸 ):)gulp-watch除了以上 4 个插件外,用 gulp-watch 也是可以的。复制代码let dest = css/;/ sass - cssgulp.

15、task(css, function() / 任务名 return gulp.src(sass/*.scss) / 目标 sass 文件 .pipe(plumber(errorHandler: notify.onError(Error: ) .pipe(watch(sass/*.scss) .pipe(sass() .pipe(debug(title: 编译) .pipe(gulp.dest(dest););gulp.task(watch, function() gulp.watch(sass/*.scss, css););gulp-watch 也不能使用类似 gulp-concat 的工具进

16、行一对多的编译。之前关于 gulp 的基础笔记都不敢往首页发,本文发到首页,除了觉得很多人使用 gulp 可能不关注增量编译外,还想知道大家在实际的开发中使用的增量编译插件方式是?个人觉得 gulp-cached+gulp-remember 的搭配不错,不过我还没在实际开发中用过 gulp,所以想听听老司机的意见。参考资料:Gulp.js是目前前端非常流行的自动化构建工具,它基于流,代码优于配置,API简单,又有着大量优秀的第三方插件。它的gulp.watch()接口,可以让我们监听文件改动而进行自动构建,但是如果存在耗时的任务或者随着项目的逐渐增大,可能每次构建都要花费很多的时间,那么在Gu

17、lp中有什么解决的办法呢?其实在Gulp的文档中对于增量编译有推荐下面4个插件:gulp-changed - only pass through changed filesgulp-cached - in-memory file cache, not for operation on sets of filesgulp-remember - pairs nicely with gulp-cachedgulp-newer - pass through newer source files only, supports many:1 source:dest那么他们的具体用法和区别是什么呢?gulp

18、-cachedgulp-cached可以将第一次传递给它的文件内容保留在内存中,如果之后再次执行task,它会将传递给它的文件和内存中的文件进行比对,如果内容相同,就不再将该文件继续向后传递,从而做到了只对修改过的文件进行增量编译。var gulp = require(gulp);var less = require(gulp-less);var cached = require(gulp-cached);gulp.task(less, function() gulp.src(./src/*.less) .pipe(cached(less) .pipe(less() .pipe(gulp.de

19、st(./dist););gulp.task(watch, function() gulp.watch(src/*.less, less););gulp-cached插件还可以接收一个可选的optimizeMemory参数,插件默认会将文件内容保存在内存中,如果将optimizeMemory设置为true,那么会转而将文件的md5值保留在内存中,从而减少对内存的占用,但是另一方面计算md5值也会消耗更多的时间,插件的作者建议在一般情况下,并不需要开启这个功能。但是,gulp-cached在使用时也有一些限制,比如下面的例子:var gulp = require(gulp);var cached

20、 = require(gulp-cached);var remember = require(gulp-remember);var less = require(gulp-less);var concat = require(gulp-concat);gulp.task(concat, function() gulp.src(./src/*.less) .pipe(cached(concat) .pipe(less() .pipe(remember(concat) .pipe(concat(all.css) .pipe(gulp.dest(./dist););gulp.task(watch,

21、function() gulp.watch(src/*.less, concat););这是一个监听less文件改动并自动编译成css文件后合并的task,考虑一下这种情况,在修改文件a.less后,触发了concat的task,但是由于此时并没有修改文件b.less,所以传递给gulp-concat插件的b.less被gulp-cached过滤掉了,导致最后生成的all.css文件中只有修改后的a.less编译成的内容。那如何解决这个问题呢,此时就需要借助gulp-remember了。gulp-remembergulp-remember同样可以在内存中缓存所有曾经传递给它的文件,但是它和gu

22、lp-cached的区别是,在之后的task中,gulp-cached会过滤掉未经修改的文件不再向下传递,而gulp-remember则会将未传递给它的文件进行补足从而能够继续向下传递,因此通过gulp-cached和gulp-remember的结合使用,既能做到只对修改过的文件进行编译,又能做到当相关联的文件任意一个发生改变时,编译所有相关的文件。var gulp = require(gulp);var cached = require(gulp-cached);var remember = require(gulp-remember);var less = require(gulp-les

23、s);var concat = require(gulp-concat);gulp.task(concat, function() gulp.src(./src/*.less) .pipe(cached(concat) .pipe(less() .pipe(remember(concat) .pipe(concat(all.css) .pipe(gulp.dest(./dist););gulp.task(watch, function() gulp.watch(src/*.less, concat););由于在第一次合并文件时,gulp-remember已经将传递过来的文件缓存在内存中了,那么

24、即使在后续的task执行中,gulp-cached插件过滤掉了未经修改过的less文件,但是gulp-remember还是能够通过自己的缓存来补全这些缺失的文件,从而做到正确地合并文件。你可能要问了对于这种情况,为什么还要额外引入两个插件,直接监听文件改动重新编译不就好了么?gulp.task(concat, function() gulp.src(./src/*.less) .pipe(less() .pipe(concat(all.css) .pipe(gulp.dest(./dist););相比上面这种不使用插件方式,gulp-cached和gulp-remember的结合使用还是有一定

25、优势的:gulp-remember缓存的是less文件编译后生成的css文件,这样只有修改了的less文件才需要重新编译成css文件,其他less文件对应的css文件可以直接从gulp-remember的缓存中读取,而不使用插件的方式每次都要重现编译所有的less文件。另外,不要忘了我们还可以合理的管理两个插件的缓存:gulp.task(watch, function() var watcher = gulp.watch(./src/*.less, concat); watcher.on(change, function(event) console.log(event.type); if (

26、event.type = deleted) delete cached.cachesconcatevent.path; remember.forget(concat, require(gulp-util).replaceExtension(event.path, .css); ););gulp-changedgulp-changed插件也能够像gulp-cached插件一样过滤未修改过的文件做到增量编译,不同之处主要在于如何判断文件被修改过,gulp-cached是通过对文件设置缓存来进行比较,而gulp-changed则是通过比较源文件和生成文件。var gulp = require(gul

27、p);var changed = require(gulp-changed);var imagemin = require(gulp-imagemin);var pngquant = require(imagemin-pngquant);gulp.task(img, function() gulp.src(./src/img/*) .pipe(changed(./dist/img) .pipe(imagemin( progressive: true, use: pngquant() ) .pipe(gulp.dest(./dist/img););gulp.task(watch, functio

28、n() gulp.watch(src/img/*.png, img););由于gulp-changed是比较源文件和生成文件,所以调用插件的时候,要传入生成的位置,一般就是最后gulp.dest()方法要传入的参数。插件默认比较的是文件修改的时间,如果不同,就说明源文件有被修改过。另外可以通过hasChanged参数来使用插件内置的另一种比较方式:changed(dist, hasChanged: pareSha1Digest),也就是通过计算文件内容的sha1值来比较,一般情况下,生成文件的内容都是不同于源文件的,除非只是简单的拷贝,所以说基本上没什么用,hasCanged参数也支持传入一个

29、函数来进行自定义比较。在使用gulp-changed插件时有一个需要注意的地方,如果在task中改变了文件的后缀名,那么就需要通过extension参数来指定新的后缀名,否则插件无法找到生成的文件,比较令人遗憾的是,对于这种情况gulp-changed插件不会有任何提示,只是默默的执行了task,但是完全没有起到增量编译的目的。var gulp = require(gulp);var changed = require(gulp-changed);var less = require(gulp-less);gulp.task(less, function() gulp.src(./src/*.

30、less) .pipe(changed(./dist, extension: .css ) .pipe(less() .pipe(gulp.dest(./dist););gulp.task(watch, function() gulp.watch(src/*.less, less););gulp-newergulp-newer既可以像gulp-cached/gulp-changed那样1对1地进行增量编译,也可以像gulp-cached配合gulp-remember那样多对1地进行增量编译。它实现增量编译的原理和gulp-changed相同,都是通过比较源文件和生成文件,只不过它只支持比较修改

31、时间。先来看一个1对1进行增量编译的例子:var gulp = require(gulp);var newer = require(gulp-newer);var less = require(gulp-less);gulp.task(less, function() gulp.src(./src/*.less) .pipe(newer( dest: ./dist, ext: .css ) .pipe(less() .pipe(gulp.dest(./dist););gulp.task(watch, function() gulp.watch(src/*.less, less););多对1增量

32、编译的例子如下:var gulp = require(gulp);var newer = require(gulp-newer);var less = require(gulp-less);gulp.task(less, function() gulp.src(./src/*.less) .pipe(newer(./dist/all.css) .pipe(less() .pipe(concat(all.css) .pipe(gulp.dest(./dist););gulp.task(watch, function() gulp.watch(src/*.less, less););我目前的看法是

33、借助gulp-newer进行多对1的增量编译和直接监听文件自动编译的区别并不是很大(它和gulp-cached配合gulp-remember使用还是有区别的,没有办法带来之前说的缓存编译结果的好处),可能唯一的好处就是下面说的这种情况:通过gulp.watch()监听了所有的文件,但是触发task的源文件只有a文件和b文件,那么此时修改不相关的c文件,gulp-newer可以防止重复编译a文件和b文件情况的出现。关于gulp-newer和gulp-changed,你也可以参考下Sflow上对他们的比较。gulp-watch除了上面介绍的和gulp.watch()配合使用的4个插件外,我们还可以

34、直接借助gulp-watch插件来完成增量编译。var gulp = require(gulp);var watch = require(watch);var less = require(less);gulp.task(watch-less, function() gulp.src(./src/*.less) .pipe(watch(./src/*.less) .pipe(less() .pipe(gulp.dest(./dist););gulp-watch可以做到和gulp原生APIgulp.watch()一样监听文件改动,并且由于它是整个task的一环,因此每次文件改动时,只有这个被改动的文件会被gulp-watch继续向下传递,而且这种写法也更接近于我们使用gulp插件的方式。另外还有的一个好处是执行watch-lesstask,会自动运行一次编译less的task,而gulp.watch()在启动时,则什么都不会做。不过gulp-watch也有它的限制,无法处理concat这样的task,具体原因可以参考这里。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com