也算是用了半年Grunt,几个月前也写过一篇它的入门文章(点此查看),不得不说它是前端项目的一个得力助手。不过技术工具跟语言一样日新月异,总会有更好用的新的东西把旧的拍死在沙滩上(当然Grunt肯定没死,gulp也不是多新颖的东西)。

看标题很明显知道相比Grunt,我会更为推崇gulp,不是说Grunt不好,而是gulp效率更高、健壮性更好,配置也更为简单,自然也值得我们为它任性一回。

先谈谈上述提到的gulp的优越性:

一. 性能更高

相对Grunt频繁的IO操作读写,gulp是将项目任务流程以streaming(流)的形式来做管道化处理,这句话怎么理解呢?

比如一个文件A,Grunt按顺序会有三个组件任务a、b、c 要对起进行处理,那么流程可能是这样的:

读取A → A.a() → 写A  → 读取A → A.b() → 写A  → 读取A → A.c() → 写A  → complete/watch...

那么换成gulp又是怎样的一个过程,它大概是这么处理:

读取A并转为流信息 → A.a() → A.b()  → A.c() → 写A  → complete/watch...

可以看到执行任务的过程,是减少了(3-1)处对文件A的读/写操作,减轻了磁盘IO操作负担,效率自然也得到明显提升。

至于“”的概念,可以戳这里了解一下。大致是读取文件时,不按常规那样把文件一口气写入内存中,而是把文件转为数据流,收到多少数据就处理多少数据,像经过竹筒的涓涓流水那样,有水源过来了就马上处理后(你可以假设竹筒在这里有净水的过滤作用)再送出去,直到水源全部“流”过该竹筒。

那么“管道化”处理又是怎样的概念?

它很类似jQuery中的链式写法,在nodeJS中管道式方法的api一般为.pipe() ,比如

XXXX.pipe(a())  //处理a任务
.pipe(b()) //处理b任务
.pipe(c()) //处理c任务

你也可以理解为上述的涓涓流水经过一排竹筒后,紧接着流向下一个竹筒,一直这样循环,直到流过最后一个竹筒(当然流水依旧代表数据,竹筒代表任务)。

二. 健壮性更好

gulp走的是递归编译的解析方式,有助于项目优化的健壮性。打个比方,比如我们使用sass来编写样式,其中b.scss引入了_a.scss文件,如果我们修改了_a.scss的内容,gulp会即时更新b.scss对应的b.css编译文件,但Grunt是基于缓存机制的,故不会重新编译b.scss文件,导致问题。

三. 配置更简洁

其实之前写的那篇Grunt入门的文章,我的确不懂到底要如何介绍Gruntfile.js的配置——略复杂和混乱,鄙人口才也不好,便草草几句话带过,相信读者可能也不太能够理清头绪。而gulp使用了node的流式管道化(pipe)处理,其配置和写法变得简洁、统一了许多,自然也方便理解。

为你的项目搭建gulp任务

搭建gulp其实很简单,就俩步骤——在项目根目录下安装所需组件,并配置一份gulpfile.js。

我们假设我们有一个放在D盘下的项目 D:/project,里面的文件结构是这样的:

我们打算利用gulp把RAW文件夹下的js和sass文件编译/压缩后都输出到COMPRESS文件夹下。

一. 安装组件

gulp自己有官方的组件推荐/查找页面(点我进入),就我们上述项目要求而言,我个人推荐下述几个组件:

  gulp   //这个是必须安装的,没有它,其它组件都用不了(注意watch组件直接集成在gulp中了,无需额外安装watch组件)
  gulp-sass    //编译sass用的
  gulp-sourcemaps    //编译sass时生成额外的.map文件用的(有啥用?看我这篇文章
  gulp-mini-css    //压缩css使用的
  gulp-uglify    //压缩、混淆js文件用的

组件的安装很简单,直接npm安装即可,比如安装gulp:

npm install gulp

安装过程可能会遇到组件被墙导致连接不上镜像的问题,解决方法有两个,一个是翻墙,另一个是走cnpm镜像(点此查阅)。

组件全部安装完成后会在你的项目根目录下生成一个node_modules文件夹,用来存放组件模块:

二. gulpfile.js文件配置

如同Grunt需要配置Gruntfile.js文件来告知node我要用什么组件并以怎样的流程来执行任务,gulp也需要在项目根目录配置一个gulpfile.js文件。
我们新建一个gulpfile.js文件,先在之中输入下面内容:

var gulp = require('gulp'),
sass = require('gulp-sass'),
mincss = require('gulp-mini-css'),
sourcemaps = require('gulp-sourcemaps'),
uglify = require('gulp-uglify');

浓浓的commonJS风,告知node我们要使用哪些组件模块来完成任务。
接着我们进一步配置文件,告诉node我们具体要以怎样的流程来执行任务,这是完整的gulpfile.js文件内容:

var gulp = require('gulp'),
sass = require('gulp-sass'),
mincss = require('gulp-mini-css'),
sourcemaps = require('gulp-sourcemaps'),
uglify = require('gulp-uglify'); var raw_css = './RAW/css',
com_css = './COMPRESS/css',
raw_js = './RAW/js',
com_js = './COMPRESS/js'; gulp.task('sass', function () {
gulp.src(raw_css+'/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass())
        .pipe(mincss())
.pipe(sourcemaps.write('/'))
.pipe(gulp.dest(com_css));
}); gulp.task('mincss', function () {
gulp.src(com_css+'/**/*.scss')
.pipe(mincss())
.pipe(gulp.dest(com_css));
}); gulp.task('minjs', function () {
gulp.src(raw_js+'/**/*.js')
.pipe(uglify())
.pipe(gulp.dest(com_js));
}); gulp.task('watch', function () {
gulp.watch(raw_css+'/**/*.scss',['sass']);
gulp.watch(raw_js+'/**/*.js',['minjs']);
}); gulp.task('default',function(){
gulp.run('sass','minjs','mincss');
gulp.run('watch');
});

我们拿写的最长的sass编译模块配置代码块来注释说明下:

//每个gulp.task(name, fn)都是一个任务配置模块,如本代码段定义了名为"sass"的任务的执行流程
gulp.task('sass', function () {
gulp.src(raw_css+'/**/*.scss') //gulp.src(glob)返回了一个可读的stream,如此行返回了RAW/css/下的全部(包含子文件夹里的).scss文件流
.pipe(sourcemaps.init()) //.pipe()管道化执行组件任务,此处调用gulp-sourcemaps的初始化api来处理接收的文件流(方便后续编译出.map文件)
.pipe(sass()) //执行gulp-sass组件任务,把.scss文件流编译为.css文件流
.pipe(sourcemaps.write('/')) //调用gulp-sourcemaps的写入api,额外输出.map文件流
.pipe(mincss()) //执行gulp-mini-css组件任务,压缩所有css文件流
.pipe(gulp.dest(com_css)); //gulp.dest(glob)返回一个可写的stream,如此行是将文件流写入到 COMPRESS/css 里的对应路径下
});

接着看看末尾处的两个代码段:

gulp.task('watch', function () {  //定义名为"watch"的任务
gulp.watch(raw_css+'/**/*.scss',['sass']); //监听 RAW/css 下的全部.scss文件,若有改动则执行名为'sass'任务
gulp.watch(raw_js+'/**/*.js',['minjs']); //监听 RAW/js 下的全部.js文件,若有改动则执行名为'minjs'任务
}); gulp.task('default',function(){ //每个gulpfile.js里都应当有一个dafault任务,它是缺省任务入口(类似C语言的main()入口),运行gulp的时候实际只是调用该任务(从而来调用其它的任务)
gulp.run('sass','minjs','mincss'); //gulp.run(tasks)表示运行对应的任务,这里表示执行名为'sass','minjs','mincss'的三个任务
gulp.run('watch'); //执行'watch'监听任务
});

上述的两个步骤做好后,直接输入运行 gulp 指令即可(我是在webstorm里直接写命令的):

同时可以看到COMPRESS文件夹下已经有了我们想要的编译、压缩后的文件:

另外这时候gulp已转入监听模式(虽然不像Grunt那样有“watch...”的提示),只要你修改了被监听的文件,任务会立即被执行一遍,无需再手动gulp一次。

用下来还是觉得gulp是个好东西,比Grunt更易上手,效率也更好,不过相较Grunt的“grunt-newer”组件,gulp对应功能的两个组件“gulp-changed”和"gulp-newer"貌似运行起来都达不到预想效果,比如我希望只针对我修改了的某个sass文件来做任务处理,我做了如下配置:

var gulp = require('gulp'),
sass = require('gulp-sass'),
mincss = require('gulp-mini-css'),
sourcemaps = require('gulp-sourcemaps'),
changed = require('gulp-changed'),
uglify = require('gulp-uglify'); var raw_css = './RAW/css',
com_css = './COMPRESS/css',
raw_js = './RAW/js',
com_js = './COMPRESS/js'; gulp.task('sass', function () {
gulp.src(raw_css+'/*.scss')
.pipe(changed(raw_css+'/*.scss'))
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(sourcemaps.write('/'))
.pipe(mincss())
.pipe(gulp.dest(com_css));
}); gulp.task('mincss', function () {
gulp.src(com_css+'/*.scss')
.pipe(changed(com_css))
.pipe(mincss())
.pipe(gulp.dest(com_css));
}); gulp.task('minjs', function () {
gulp.src(raw_js+'/*.js')
.pipe(changed(com_js))
.pipe(uglify())
.pipe(gulp.dest(com_js));
}); gulp.task('watch', function () {
gulp.watch(raw_css+'/*.scss',['sass']);
gulp.watch(raw_js+'/*.js',['minjs']);
}); gulp.task('default',function(){
gulp.run('sass','minjs','mincss');
gulp.run('watch');
});

结果发现依旧是整个文件夹下的文件都被做了任务处理。或许是我的配置不正确,若有了解newer或者changed的朋友望能不吝指正。

另外百度fis貌似也是另一个不错的alternative,跟gulp差不多,而且中文文档也挺详细的,之前用过百度的一些东西,感觉质量还是有保障的。

最后推荐下一个大神级朋友的博客,在我们苦口婆心的催产下他终于发表了第一篇文章,介绍的JS面向对象的思想,欢迎大家去看一看。

共勉~

是时候搁置Grunt,耍一耍gulp了的更多相关文章

  1. gulp和grunt的区别

    1. Grunt -> Gulp 早些年提到构建工具,难免会让人联想到历史比较悠久的Make,Ant,以及后来为了更方便的构建结构类似的Java项目而出现的Maven.Node催生了一批自动化工 ...

  2. Gulp vs Grunt 前端构建工具对比

    Gulp vs Grunt 前端工程的构建工具对比 1. Grunt -> Gulp 早些年提到构建工具,难免会让人联想到历史比较悠久的Make,Ant,以及后来为了更方便的构建结构类似的Jav ...

  3. 前端工程的构建工具对比 Gulp vs Grunt

    1. Grunt -> Gulp 早些年提到构建工具,难免会让人联想到历史比较悠久的Make,Ant,以及后来为了更方便的构建结构类似的Java项目而出现的Maven.Node催生了一批自动化工 ...

  4. 谈谈Grunt,NPM,Gulp

    随着前端工程化的趋势,产生了越来越多的构建工具,而其中比较优秀的就是grunt,npm,gulp,今天我来说说这三者间的区别以及他们的优缺点. 相信一般前端开发者选择构建工具的时候,更多的是看个人习惯 ...

  5. Node开发项目管理工具 Grunt 对比 Gulp

    转自Gulp vs Grunt 1. Grunt -> Gulp 早些年提到构建工具,难免会让人联想到历史比较悠久的Make,Ant,以及后来为了更方便的构建结构类似的Java项目而出现的Mav ...

  6. Appium+python自动化(二十一)- 让猴子按你指令大闹手机,让你成为耍猴高手 - Monkey(猴子) - MonkeyScript(超详解)

    简介 一年一度的暑假如期而至,每年必不可少的,便是<西游记>这部经典电视连续剧的播出,作为一名90后,对于这部经典剧的情谊,就是观看已成为一种习惯.依然深刻的记得,小时候妈妈为了催促我睡觉 ...

  7. 如何选择JavaScript构建工具之Babel、Browserify、Webpack、Grunt以及Gulp

    当我们开始一个新的 JavaScript 项目时,我们需要考虑的第一件事就是搭建一个前端编译环境.但是在面对众多的 JavaScript 构建工具时,我们却无所适从,不知道究竟哪一个才是最适合我们的. ...

  8. 送干货,实用内联gulp插件——gulp-embed

    现在npm上有很多gulp内联工具,用于把脚本和样式内嵌到HTML页面上,之前搞项目我也在这些插件中寻觅许久,但均不满足公司项目的一个需求—— HTML上同时插入了开发(dev版,src文件夹下,比如 ...

  9. Gulp 自动化的项目构建工具

    在很多场合都会听到前端工和 node 程师推荐 Grunt 来实现项目的自动化,自动化可以自动完成 javascript/coffee/sass/less 等文件的的测试.检查.合并.压缩.格式化.部 ...

随机推荐

  1. CoreCRM 开发实录 —— Profile

    再简单的功能,也需要一坨代码的支持.Profile 的编辑功能主要就是修改个人的信息.比如用户名.头像.性别.电话--虽然只是一个编辑界面,但添加下来,涉及了6个文件的修改和7个新创建的文件.各种生成 ...

  2. HTML 事件(二) 事件的注册与注销

    本篇主要介绍HTML元素事件的注册.注销的方式. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流.事件委托 4. ...

  3. 微软Azure 经典模式下创建内部负载均衡(ILB)

    微软Azure 经典模式下创建内部负载均衡(ILB) 使用之前一定要注意自己的Azure的模式,老版的为cloud service模式,新版为ARM模式(资源组模式) 本文适用于cloud servi ...

  4. tomcat开发远程调试端口以及利用eclipse进行远程调试

    一.tomcat开发远程调试端口 方法1 WIN系统 在catalina.bat里:  SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compi ...

  5. Git命令总结

    本文转载自345大神.... 查看原文 先上个图形化界面GIT工具 SourceTree下载链接 windows版 1.8.3 & Mac版 2.2.4 链接: http://pan.baid ...

  6. windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)

    本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...

  7. jquery插件的用法之cookie 插件

    一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...

  8. ubuntu系统下如何修改host

    Ubuntu系统的Hosts只需修改/etc/hosts文件,在目录中还有一个hosts.conf文件,刚开始还以为只需要修改这个就可以了,结果发现是需要修改hosts.修改完之后要重启网络.具体过程 ...

  9. 【NLP】干货!Python NLTK结合stanford NLP工具包进行文本处理

    干货!详述Python NLTK下如何使用stanford NLP工具包 作者:白宁超 2016年11月6日19:28:43 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的 ...

  10. C#文件安全管理解析

    在实际的项目开发中,我们经常需要使用到文件的I/O操作,主要包含对文件的增改删查等操作,这些基本的操作我们都是很熟悉,但是较少的人去考虑文件的安全和操作的管理等方面,例如文件的访问权限管理,文件数据的 ...