也算是用了半年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

安装过程可能会遇到组件被墙导致连接不上镜像的问题,解决方法有两个,一个是FQ,另一个是走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');
});

View Code

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

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

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

共勉~

是时候搁置Grunt,耍一耍gulp了相关推荐

  1. gulp项目部署服务器,关于部署:部署后如何在远程服务器上触发gulp / grunt任务?...

    我刚刚切换到Wordpress的Roots Sage入门主题:roots.io/sage/docs/ 我目前正在阅读有关部署过程的信息. 我的流程通常是: - 做出改变 -用咕unt声/大嘴巴建造 - ...

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

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

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

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

  4. 坐标成都!百度AI快车道与网红城市的“新耍法”你期待吗

    点击左上方蓝字关注我们 一边是满怀壮志,大手一挥的敲着键盘用代码改变世界,一边却是缺乏安全感,为了掌握最新技术不断熬夜学习的"心酸",程序员就是这样痛并快乐着的一群人.他们刚学完P ...

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

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

  6. 前端构建工具gulp之基本介绍

    1.基本介绍 gulp.js是一个自动化构建工具,是自动化项目的构建利器.可以对网站的资源进行优化,将开发过程中一些重复的任务通过执行命令自动完成.这样能很大的提高我们的工作效率. gulp.js是基 ...

  7. gulp前端自动化构建工具:常用插件介绍及使用

      Gulp是基于Node.js的一个构建工具(自动任务运行器),开发者可以使用它构建自动化工作流程(前端集成开发环境).一些常见.重复的任务,例如:网页自动刷新.CSS预处理.代码检测.压缩图片.等 ...

  8. Building with Gulp

    Building With Gulp =================== 翻译出处 对网站资源进行优化,并使用不同浏览器测试并不是网站设计过程中最有意思的部分,但是这个过程中的很多重复的任务能够使 ...

  9. 程序员如何用“撞针“拯救35亿地球人?

    春节假期即将结束,有多少程序员朋友已经离开家乡在返回北上广深等工作所在城市的路上?有多少程序员已经开工大吉开始了新一年的代码征程?回首这一个春节,8 部电影在大年初一齐上线,<流浪地球>在 ...

最新文章

  1. python3常用函数大全_Python3NumPy——常用函数
  2. 怎么向html插入广告,给blogger添加各种广告代码的方法
  3. python调研报告总结体会_学习调研心得体会
  4. 编写你的第一个 Django 应用,第 6 部分
  5. 十大排序算法之冒泡排序
  6. Uploadify——学习(1):在Struts2的使用
  7. iphone4 base64 mp3 无法解析 html5,javascript - 如何使用HTML5在firefox上播放base64音频数据? - 堆栈内存溢出...
  8. SpringIOC的创建对象的单例多例模式和自动注入
  9. python xgboost用法_XGBoost使用教程(纯xgboost方法)一
  10. qt 窗口自绘、鼠标响应拖动窗口
  11. Python:程序员在每天不同时间发微信消息给女友
  12. Pentium 4处理器架构/微架构/流水线 (7) - NetBurst前端详解 - 分支预测
  13. UEFI+GPT安装Win10和RHEL6.5双系统
  14. 学好python工资一般多少-学会Python后,月薪40k是什么水平?
  15. uBar如何设置Mac拥有Win式任务栏
  16. Netbean8.2初次运行Mavn的初始配置
  17. 超级计算机通信工程研发相关高校,美国签证技巧
  18. NVIDIA Jetson之OTA远程升级Jetpack
  19. 人活着到底为了什么?
  20. 【足迹C++primer】43、拷贝控制和资源管理

热门文章

  1. perl use 命令中指定路径
  2. 软件工程结构化建模的方法和工具_2020年6月——北京大学《软件工程》笔记
  3. IOS日历显示12个月
  4. 虚拟dom_虚拟DOM发展的前世与今身
  5. 无线密码离线破解工具Pyrit常用命令集合大学霸IT达人
  6. Swift 1.1语言第7章 函数和闭包
  7. python爬取微博指定内容_python3.5爬虫-爬取微博某博主微博内容
  8. a java_java程序弹出a java exception has occurred
  9. topic是短语还是句子_英语七下unit 5 topic 3短语句子
  10. java gui 选项_【Java-GUI】04 菜单