spud.in
域名年龄: 15年6个月21天HTTP/1.1 200 OK 服务器:nginx/1.2.3 访问时间:2015年02月07日 15:16:57 类型:text/html 文件大小:11152 修改日期:2014年04月07日 17:01:53 连接:keep-alive 接受单位:字节 页面编码:UTF-8
be fool. be cool.archivesaboutGrunt vs Gulp2014-04-03最近渐渐在把项目的构建工具从grunt换到gulp上去。也是好久没写博客了,期间想法是有过不少,都不怎么成形,过了一阵子觉得想得不太靠谱,或者就是自己懒得写,就假装什么都没发生过一样。然而发生过的终归是发生过的,哪怕最终摇摇曳曳无疾而终,记录下来以后看看也会是蛮有意思的一件事情,何况这里的主题好像也没有要无疾而终的意思。这两个东西都是构建工具。构建工具大体上就是把原料变成可口佳肴的器材。我们会希望自己代码写起来都是一个个功能分开来的,方便调试和组装。然后在发布的时候进行压缩合并,使得用户可以获得更好的加载体验。grunt的做法是定义配置文件,以编译stylus为例,写起来就是这样的:1234567891011121314151617// 写好配置grunt.initConfig({stylus:{compile: {files:[{expand: true,src:["stylus/**/*.styl"],dest:"css/",ext:".css"}]}}});// 加载插件grunt.loadNpmTasks("grunt-contrib-stylus");// 定义默认任务grunt.registerTask("default",["stylus"]);看起来不错,但同步读写文件的操作一来比较低效,二来任务复杂度上去之后,会变得繁琐起来。比如希望多个stylus文件合并到一个all.css里去。这时候要不就寄希望于grunt-contrib-stylus这个插件的内部实现对此有支持。不然就只能先得到几个中间文件,再另外通过专门用来合并的插件来做后续的事情。结束再清理掉中间文件以grunt的模式,不存在任务之间相互协作的有机方式。在处理缓存这样的应用场景时,显得尤为不便。另外,他虽有编程api,和配置文件却非一脉相承。其他许多比如files的配配置方式过于多样,以及在本身中杂糅了许多不必要的功能等等就按下不表了。gulp的设计非常的简单,他利用了node stream的便捷,把读取的文件变成一个输入流,经过一个个的管道,最终由输出流写入目标,一气呵成。而每个插件就像是一根水管,一头进,一头出,可以方便的连接组装或是嵌套。缓存也就是套在外头的一个处理器而已。关于node stream,有兴趣的同学可以玩一下substack同学的stream-adventure 这个项目。他会通过闯关的方式一步步让你了解stream和一些工具模块的使用方法,非常有趣。另外John Resig也制作了Stream Playground来帮助理解,同样很有意思回到gulp,刚才处理stylus的方法于是就变成了这样:1234567var stylus = require("gull-stylus");gulp.task("stylus", function() {gulp.src(["stylus/**/*.styl"]).pipe(stylus()).pipe(gulp.dest('./css'));});gulp.task("default",["stylus"]);好比要做一杯夏日冰饮,本来你要调好冰块,准备好浓缩果酱,按部就班的做出来。现在你有好多管子,他们会分别可以用来把水分离,制作冰块,添加果酱,再汇集。于是你把这些管子组装好,从一头把水倒下去,冰饮就从另一头出来了,非常轻松简单。看到gulp之后欢欣鼓舞的把全局的构建工具迁移了过去。我们之前用grunt的时候,希望可以把构建脚本放在全局,而不用每个项目自己去配置。但是利用grunt本身未能顺意,于是辛辛苦苦创造了hum和grunt-tube(或许是我名字是不正确,若你有好的实践请告诉我)但现在使用gulp的命令行轻松就搞定了。于是我们目前所要使用的配置大致会是这样:123 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 // 作为单独插件的rename提供了更高的灵活度 gulp.task("scripts", function(){ return gulp.src(["src/js/**/*.js"]) .pipe(rename({ suffix: '.min' })) .pipe(uglify()) .pipe(gulp.dest('dest/js/')); }); gulp.task("css",function(){ return gulp.src(['src/css/**/*.css']) .pipe(rename({suffix: '.min'})) .pipe(minifycss()) .pipe(gulp.dest('dest/css/')); }); gulp.task("image",function(){ return gulp.src(["src/img/**/*.{gif,jpg,png}"]) .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))) .pipe(gulp.dest('dest/img')); }); gulp.task("upload",function(){ return gulp.src('dest/**/*') .pipe(ftp(ftpconfig)); }); // 为了保证upload可以在其他处理都并行完成之后执行 // 需要其他task把处理流程return,并把upload写在最后的回调中 gulp.task('default', ['scripts','css','image'], function(){ gulp.start('upload'); }); 以上这般之后,把文件存于 ~/.gulp/gulpfile.js,就可以在任何其他目录执行 gulp --gulpfile ~/.gulp/gulpfile.js --cwd . 来进行处理了。如果你热爱偷懒,完全可以把这句在写成一条shell命令。 想来快两年之前,我们筹划开始写自己的构建工具。一年多以前grunt悄然兴起,那个时候也有写过文章罗列grunt的可取之处。然而短短一年时间过去,却似已有英雄迟暮之态。我想说的是,当遇见足够”好味”的选择的时候,哪怕之前的方案有花过再多力气,下决定的时刻都能感到一阵轻松与畅快。技术虽然不断的在发展前进,新诞生的技术却是在变得越来越容易学习接受。 对于后来的人们,可以直接跳过错误的尝试,在一开始就遇上更正确的做法,真是意见很幸运的事情。然而,见证过这些变化的来去,了解简单与复杂之间的摇摆,回味起来大概会更有滋味一些。 天气渐渐热起来,不如从头学学看如何做一杯饮料。 leave comment
© 2010 - 2020 网站综合信息查询 同IP网站查询 相关类似网站查询 网站备案查询网站地图 最新查询 最近更新 优秀网站 热门网站 全部网站 同IP查询 备案查询
2025-09-27 16:43, Process in 0.0034 second.