gulp
2015-11-09 20:25
459 查看
gulp
一、前言
gulp是一个适用于javascript的构建工具,能自动执行已定义的常见任务,如语法检测(jshint)、测试(mocha)、压缩(uglify)等。其相当于maven之于java。还有一个更早出现的构建工具grunt,其也提供了gulp的功能,且功能更为强大,但其在配置及使用上更为繁琐,其实现的理念也导致其编译效率较低,新出现gulp的出现正是为了解决这些问题,在后面的使用过程中将逐渐对比两者的优劣。
官网: http://gulpjs.com/
中文:http://www.gulpjs.com.cn/
二、安装
npm install -g gulp
gulp提供的是一个构建工具,要真正实现我们需要的功能,还需要下载相关的插件,如
npm install gulp-uglify --save-dev
三、使用API:
下面通过实现一个gulp的demo,来学习其API。创建gulp文件夹,新建gulpfile.js作为gulp的启动文件,插入如下代码
var gulp = require('gulp'); gulp.task( 'default', function(){ console.log( 'this is gulp default' ); });
使用cli进入到 gulp目录,执行gulp,其会自动找到gulpfile.js并执行,打印信息如下
cc@cc:~/Work/gulp$ gulp [07:23:15] Using gulpfile ~/Work/gulp/gulpfile.js [07:23:15] Starting 'default'... this is gulp default [07:23:15] Finished 'default' after 133 μs
执行完后会自动退出,后面会有不自动退出的情况,μs是微秒单位
现在我们按一个较正规的系统目录,参照前面几章实现的项目。
cli到gulp目录下,执行 npm init,自行配置相关描述,可如下
{ "name": "gulp", "version": "1.0.0", "description": "this is a demo for gulp", "main": "index.js", "dependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "upopen.cn", "license": "ISC" }
gulp下新建assets/core/js/base.js,插入
function base( name ){ console.log( 'this is base, hi ' + name ); }
再新建assets/core/css/common.css,插入
body{ margin: 0; padding: 0; background: #afafaf; } a{ text-decoration: none; }
下载基于uglify的代码压缩插件 gulp-uglify
cli执行 npm install gulp-uglify --save-dev
修改gulpfile.js
var gulp = require( 'gulp' ), uglify = require( 'gulp-uglify' ); gulp.task( 'default', function(){ gulp.src( 'assets/core/js/base.js' ) .pipe( uglify() ) .pipe( gulp.dest( 'assets_min' ) ); });
cli执行gulp
即实现了将assets/core/js/base.js压缩并插入到新建文件夹 assets_min内,和nodejs写法很相同,且条目简单,若用grunt做同样的功能则需要做相当多的配置。
gulp的API总共有四个,我们一次就用到了其中的三个。
gulp.task( name[, deps], fn ):创建一个任务
name: String 任务名 deps: Array 任务依赖,其会在任务之前执行 fn: Function 任务事件
cli执行gulp时,默认会执行gulpfile.js里的default任务,若需执行其它任务,可以将其它任务作为default的deps,如
var gulp = require( 'gulp' ), uglify = require( 'gulp-uglify' ); gulp.task( 'default', [ 'minify' ] ); gulp.task( 'minify', function(){ gulp.src( 'assets/core/js/base.js' ) .pipe( uglify() ) .pipe( gulp.dest( 'assets_min' ) ); });
若只是想单独执行minify,也可以通过cli执行 gulp minify,来显示执行指定的task
fn函数内的常见形式是 gulp.src( 'assets/core/js/base.js' ).pipe( uglify() ),读取文件.pipe( 执行压缩 ).pipe( 添加到文件夹 ),pipe是用流传递操作后的数据,下一个pipe接收到数据做操作后再向后传递,比起grunt的创建临时文件效率更高。可以通过输出src的引用查看
var stream = gulp.src( ... ).pipe( .. ) console.log( stream );
文件流的工作原理 https://github.com/substack/stream-handbook
fn 也支持异步的形式,需要在function添加实参cb,当异步返回时执行cb()即可,和mocha的回调添加实参done同理,如
var exec = require('child_process').exec; gulp.task('jekyll', function(cb) { exec('jekyll build', function(err) { if (err) return cb(err); cb(); }); });
注意task默认将以最大的并发数执行,多个task之间不会相互等待,若需序列执行,注意使用deps 及 异步情况
gulp.src( globs[, options ] )
读取指定路径的文件,输出到piped的下一个插件中。
globs的语法 https://github.com/isaacs/node-glob
globs可以为Array / String,如上例中,可以是
'assets/core/js/base.js' 'asserts/*/*/base.js' 'asserts/*/*.js' [ 'assets/*/*.js' ]
更多匹配规则可以参考 https://github.com/isaacs/minimatch
注意 * 的用法,/*.js,表示当前子目录的所有js文件,而/*/*.js,其N级下的子目录,即当有多层子目录时,不需要添加多层的*
options可以配置
buffer: true | false 是否以流的形式传播 read: true | false 是否可读 base: ''
其中只base作为统一路径可能被使用外,其它两个基本不会使用,后面会用到base
gulp.dest( path[, options ] )
将接收到的数据输出到path下,若path不存在,会自动创建
path: String | Function,可据fun生成路径 options: 几乎不用 cwd: String 输出当前路径 mode: 0777,用于配置权限
注:需要注意path的使用,其和gulp.src里的glob及 options里的base设置是相关,
注意上例中以下几种情况
gulp.src( 'assets/core/js/base.js' ).pipe( gulp.dest( 'assets_min' ) ); //assets_min/base.js gulp.src( 'assets/core/**/base.js' ).pipe( gulp.dest( 'assets_min' ) ); //assets_min/js/base.js gulp.src( 'assets/**/**/base.js' ).pipe( gulp.dest( 'assets_min' ) ); //assets_min/core/js/base.js gulp.src( 'assets/core/**/base.js',{base: 'assets'}).pipe( gulp.dest( 'assets_min' ) ); //assets_min/core/js/base.js
可以看出path取的是 **部分,若设置了base,则取base后的部分。
实现一个更复杂些的例子来表现gulp的用法。
在assets/core/js/ 下与base.js同级新建common.js
新增语法检测插件jshint,及文件组合插件concat。
cli下执行 cnpm install gulp-jshint gulp-concat --save-dev
修改gulpfile.js
var gulp = require( 'gulp' ), uglify = require( 'gulp-uglify' ), jshint = require( 'gulp-jshint' ), concat = require( 'gulp-concat' ); gulp.task( 'default', function(){ gulp.src( 'assets/core/**/**.js',{ base: 'assets' } ) .pipe( jshint() ) .pipe( uglify() ) .pipe( concat( 'all.js' ) ) .pipe( gulp.dest( function(){ return 'assets_min' } ) ) });
读取assets/core/js下的base.js、common.js --> jshint语法检测 --> uglify压缩 --> concat合并为all.js --> 添加到 assets_min 文件夹下
再讲下gulp的第四个API
gulp.watch( glob[, options ], task );
gulp.watch( glob[, options ], cb );
glob: String | Array 监听文件的路径 options: tasks: Array 当被监听的文件变动时,需要执行task cb: function 当文件变化时可执行的函数,
在gulpfile.js文件里追加
gulp.watch( 'assets/**/**.js', [ 'default' ] ); gulp.watch( 'assets/**/**.js', function( event ){ console.log( event ); })
cli重新执行gulp,相比之前可以看到cli下并没有自动退出,此时修改assets/core/js/base.js保存后,cli自动显示执行了default,并且输出了{ type: 'changed',path: '/home/cc/Work/gulp/assets/core/js/common.js' },即event表示文件的操作type及path。 打开assets_min下的all.js,可以看到修改后的内容也已经添加进来了。
gulp.watch本身会返回一个实例
其提供了events( change | end | error | ready | nomatch ) 及 method ( end | files | add | remove )
上面为watch追加的代码,可以修改为
var watcher =gulp.watch( 'assets/**/**.js', [ 'default' ] ); watcher.on( 'change', function( event ){ console.log( event ); });
可以达到同样的效果
四、插件Plugin
gulp作为一个构建工具,其只是提供了一个平台,可运行各款插件,以达到我们的项目需求,所以当我们学会使用gulp后,还需要了解其提供了哪些插件,甚至对没有提供的插件,我们可以自行封装。
插件列表 http://gulpjs.com/plugins/
常用的插件有
压缩CSS(gulp-minify-css) 语法检查(gulp-jshint) 文件拼接(gulp-concat) 文件压缩(gulp-uglify) 图片压缩(gulp-imagemin) 实时加载(gulp-livereload) 文件清理(gulp-clean) 更新通知(gulp-notify) 图片快取(gulp-cache) Autoprefixer(gulp-autoprefixer)
当需要引用的插件列表较多时,可以使用gulp-load-plugins模块,代替所有插件的require,于是前面demo也可以写成
var gulp = require( 'gulp' ), plugins = require( 'gulp-load-plugins' )(); gulp.task( 'default', function(){ gulp.src( 'assets/core/**/**.js',{ base: 'assets' } ) .pipe( plugins.jshint() ) .pipe( plugins.uglify() ) .pipe( plugins.concat( 'all.js' ) ) .pipe( gulp.dest( function(){ return 'assets_min' } ) ); });
注意各插件的命名。
五、browser-sync
再介绍一个很酷的功能browser-sync。
当我们修改html/css/js等静态资源文件时,需要刷新才能看到效果,如果做测试时填写了一堆表单,还需要重新来做,browser-sync就提供这样的功能。不过其目前只在修改css文件时做到单独加载,Html/Js 的自动刷新还是全页面的。
cli上执行 npm install browser-sync --save-dev
在当前demo下新建views/index.html,引入上例中的 css / js,如下
<!DOCTYPE html> <html> <head> <link href="../assets/core/css/common.css" type="text/css" rel="stylesheet" /> </head> <body> this is a demo for browser-sync <input type="text" /> <script src="../assets/core/js/common.js"></script> </body> </html>
在gulpfile.js后追加代码
... var browserSync = require( 'browser-sync' ); ... gulp.task( 'browser-sync', function(){ var files = [ 'views/*.html', 'assets/**/*.js', 'assets/**/*.css' ]; browserSync.init( files, { server: { baseDir: '' } }) })
启动gulp,提示
cc@cc:~/Work/gulp$ gulp [16:02:41] Using gulpfile ~/Work/gulp/gulpfile.js [16:02:41] Starting 'browser-sync'... [16:02:41] Finished 'browser-sync' after 35 ms [16:02:41] Starting 'default'... [16:02:41] Finished 'default' after 310 ms [BS] Access URLs: ------------------------------------- Local: http://localhost:3000 External: http://172.16.22.29:3000 ------------------------------------- UI: http://localhost:3001 UI External: http://172.16.22.29:3001 ------------------------------------- [BS] Serving files from: ./ [BS] Watching files...
浏览器自动打开 localhost:3000,显示cannot get /,补全网址 localhost:3000/views/index.html,即打开了前面定义的html,此时对该html及引用的common.js /common.css的任何保存操作,都会导致资源自动更新,其中css的修改,只会更新当前资源,不会导致页面的整体刷新。
相关文章推荐
- 谈Dubbo服务框架(顶)
- 4,Xcode的调试
- C++设计模式[八]装饰模式
- swift中的类和结构
- 继承与接口动手动脑
- webForm练习1(地区导航)
- 【转】JDBC为什么要使用PreparedStatement而不是Statement
- git 将自己本地的代码建立分支推送到远程仓库
- hdu 3264 Open-air shopping malls(几何)
- 【Codeforces Round 324 (Div 2)A】【水题】Olesya and Rodion 构造数长度为n且是t的倍数
- iOS学习XMPP之电子名片模块
- Java中LinkedHashMap的实现
- UILabel
- eclipse 运行 动态web工程出错
- ReactiveCocoa基础知识内容
- 1、搭建springMVC开发环境以及HelloWorld测试
- 商城架构二
- C++学习——父类指针和子类指针的步长问题
- OC中字典的操作方法 集合 动态排序
- 小马哥---高仿红米1s 远程修复系统 开机界面与修复提取界面 6572