学习自动化工具gulp
<什么是gulp>官网地址:http://gulpjs.com/
gulp是可以自动化执行任务的工具,在开发流程里,一定有一些动作需要手工的重复的去执行,例如:
·把一个文件拷贝到另外一个位置
·把多个js或者css文件合并成一个文件,以减少网络请求数,同时可以进行压缩,去掉空格回车等浏览器不需要的部分
·把sass或者less文件编译为css
·压缩图像文件,以减少网络流量
·创建一个可以实时刷新页面内容的本地服务器等等
一般需要重复执行的动作,都可以创建成一个gulp任务,然后在指定的条件下,比如文件发生变化后,自动去执行这些任务
<gulp的特点>
·易于使用 通过代码优于配置的策略,gulp让简单的任务简单,复杂的任务可管理
·快速构建 利用nodejs流的威力,可以快速的构建项目并减少频繁的IO操作,前一级的输出,直接变成后一级的输入,使得在操作上非常简单
·高质量的插件 gulp严格的插件指南确保插件可以简洁的工作
·易于学习 API很少(核心方法也就4个)
对比grunt与gulp,用一辆载有货物的火车说明:grunt就好比每次在中转站,都要将车上的货物卸下来,再换量新的火车(有较多的临时文件等);而gulp就好比在中转站的时候,只需要更换新的车头就可以,不需要重新的卸货装货的步骤。
<gulp中的流>
·gulp是通过流和代码优于配置的策略(grunt只基于配置的,不好管理)来尽量简化任务编写的工作
·类似jQuery里的链式操作,把各个方法串联起来构建完整的任务
·用gulp编写任务也可看作是用nodejs编写任务
·当使用流时,gulp不需要生成大量的中间文件,只将最后的结果写入磁盘,整个过程因此变得非常快
<gulp的安装>
要想在项目中使用gulp,需要两点:
·在全局范围内去安装一下gulp的命令行工具
·然后在项目里面再本地安装gulp
<gulp命令行工具>
·使用npm install -g在全局范围内安装
·一般用npm安装的时候用-g的参数,就表示这个安装的东西会作为命令去执行
·若是在mac或者linux下遇到了权限问题,需要在命令前面加上sudo,即sudo npm install gulp -g
安装完成后输入 gulp --help,如果输出一些帮助的信息就表示gulp命令行安装成功了。如果安装不成功,可以试试换成国内的源:
淘宝源:npm install -g gulp --registry=http://registry.npm.taobao.org
中国源:npm install -g gulp --registry=http://registry.cnpmjs.org
官方源:npm instal -g gulp --registry=http://www.npmjs.org/
<项目下安装gulp>
npm install gulp --save-dev
将gulp作为项目的开发依赖(只在开发时用,不会发布到线上)。在node_modules下安装本地的gulp库并添加配置到package.json文件的devDependencies中。
<gulp运行>
·创建配置文件
gulp的任务要放到一个叫gulpfile.js的文件里面。先在项目的根目录下面创建一个这样的文件。然后在这个文件的顶部添加如下代码:
var gulp = require("gulp")
通过require把gulp模块引入当前项目并赋值给gulp变量,这样,gulp变量里面就有了gulp的所有方法
·创建gulp的任务
使用gulp的task方法,第一个参数是任务的名称,第二个参数是任务的定义(一个匿名函数)
gulp.task("hello",function(){ console.log("你好,世界"); }) //执行gulp的任务,打开命令行工具,进入到项目所在的目录,然后执行gulp hello
//gulp可以连续执行多个任务 gulp task1 task2....
<gulp命令行>
·-v或-version 显示版本号
·--gulpfile 手动指定一个gulpfile的路径
·--cwd dirpath 指定当前目录,即从哪个工作目录开始查找
·-T或--tasks 显示task依赖树。gulp任务之间可以相互依赖
·--color
·--no-color
·--silent 禁止所有的gulp日志
<gulp工作方式>
gulp.js的使用流程一般是:先通过gulp.src()方法获取到想要处理的文件流,然后把文件流通过pipe方法导入到gulp的插件中。最后把经过插件处理后的流再通过pipe方法导入到gulp。dest()中,gulp.dest()方法则把流中的内容写入到文件中,dest方法的参数是个路径,如果路径不存在,则会创建。
·gulp.src() 在gulp中,使用的是nodejs中的stream,首先获取需要的stream,然后通过stream的pipe()方法把流导入到你想要的地方,比如gulp的插件中,经过插件处理后的流又可以继续导入到其他插件中,当然也可以把流写入到文件中,所以gulp是以stream为媒介的。它不需要频繁的生成临时文件,这也是gulp的速度比grunt快的一个原因。gulp.src()是用来获取流的,但这个流里的内容不是原始的文件流,而是一个虚拟文件对象流,这个虚拟文件对象中存储着原始文件的路径、文件名、内容等信息。
//src方法读出的对象流(流不再是buffer格式,而是一个个的对象)的格式 var File = require("vinyl");//虚拟文件对象流模块 var coffeeFile = new File({ cwd:"/",//当前工作路径 base:"/test/",//基准路径 path:"/test/file.coffee",//文件的完整绝对路径 contents:new Buffer("test=123") //文件的内容
... })
·gulp.dest() 用来写文件的。给gulp.dest()传入的路径参数,只能用来指定要生成的文件的目录,而不能指定生成文件的文件名,它生成文件的文件名使用的是导入到它的文件流自身的文件名,所以生成的文件名是由导入到它的文件流决定的,及时我们给dest传入一个带有文件名的路径参数,它也会把这个文件名当做是目录名。若是想要改变文件流的文件名,可以参考使用gulp-rename。dest的目标路径是原始路径去掉base路径。
·gulp.task() 执行多个任务时怎么控制任务执行的顺序。gulp中执行多个任务,可以通过任务依赖来实现,例如有one、two、three三个任务,那就可以定义一个空的任务,然后把三个任务当做这个空任务的依赖就可以了。
//只要执行default任务,就相当于one,two,three三个任务执行了 gulp.task('default',['one','two','three'])
如果任务之间没有依赖,则任务会按照书写顺序来执行,如果有依赖的话则会先执行依赖的任务,但是如果某个任务所依赖的任务是异步的,gulp并不会等待那个依赖的异步任务执行完成,而是会直接执行后续的任务。
tips:如果想等异步任务中的异步操作执行完成后再执行后续的任务,有三种方法可以实现:
1,在异步操作完成后执行一个回调函数来通知gulp这个异步任务已经完成,这个回调函数就是人物函数的第一个参数
gulp.task('one',function(cb){//cb为人物函数提供的回调,用来通知任务已完成 setTimeout(function(){ cb()//异步操作完成,执行回调 }) })
2,返回一个promise对象
//一个著名的异步处理的库,https://github.com/kriskowal/q var Q = require("q"); gulp.task('one',function(){ var deferred = Q,defer();//创建一个defer事件延迟对象 setTime(function(){ deferred.resolve('成功');//异步事件完成 },5000) return deferred.promise; }) gulp.task("two",["one"],function(){ console.log("two done"); })
·gulp.watch() 用来监听文件的变化,当文件发生变化后,我们可以利用它来执行相应的任务,例如文件压缩等。
gulp.task('default',function(){ gulp.watch("app/**/*.js",['one','two','three']) }) //监控的任务都不会停止
//
//gulp.watch还有另外一种使用方式 gulp.task("js/*.js",function(event){ //每当文件发生变化时,就会调用这个函数,并且传入一个event对象,该对象包含了文件变化的一些信息,type属性是变化的类型(有added,changed,deleted),path属性为发生变化的文件的路径 console.log(event.type) console.log(event.path) })