一、gulp是什么
gulp就是用来机械化的完成重复性质(如less->css;js、css压缩;js混淆)的工作;gulp的机制就是将重复工作抽象成一个个的任务。
二、gulp使用
a.首先确保电脑上已经正确安装了node环境;
b.其次再全局安装gulp,命令行语句:npm install -g gulp;
c.在项目根目录下添加一个gulpfile.js文件,这个是gulp的主文件,这个文件名是固定的;d.在gulpfile中抽象我们需要做的任务。
小案例:
'use strict'; //在gulpfile中先载入gulp包,因为这个包提供了一些API var gulp=require('gulp'); var less=require('gulp-less'); var cssnano=require('gulp-cssnano'); var concat=require('gulp-concat'); //1.less编译 压缩 合并:此处没有演示导包,因为一般预处理css(如less sass)都可以导包 gulp.task('style',function(){//style为任务名 //这里是在执行style任务时自动执行的 gulp.src(['src/styles/*.less','!src/styles/_*.less'])//指不获取_*.less .pipe(less()) .pipe(cssnano())//压缩 //在cmd中执行gult style后会在根目录下自动生成dist/styles/app.css .pipe(gulp.dest('dist/styles')) .pipe(browserSync.reload({ stream: true }));//重新刷新; }) //2.JS合并 压缩 混淆 var uglify=require('gulp-uglify'); gulp.task('script',function(){ gulp.src('src/scripts/*.js') .pipe(concat('all.js')) .pipe(uglify()) .pipe(gulp.dest('dist/scripts')) .pipe(browserSync.reload({ stream: true }));//重新刷新 }) //3.图片复制,会在根目录下生成dist/images/pipe.png,即把 //src/images下所有的图片都生成到目录dist/images下 gulp.task('image',function(){ gulp.src('src/images/*.*') .pipe(gulp.dest('dist/images')) .pipe(browserSync.reload({ stream: true }));//重新刷新; }) //4.html var htmlmin=require('gulp-htmlmin') gulp.task('html',function(){ gulp.src('src/*.html') .pipe(htmlmin({ collapseWhitespace:true,//压缩 removeComments:true//压缩后去掉注释 })) .pipe(gulp.dest('dist')) .pipe(browserSync.reload({ stream: true }));//重新刷新 }) //5.server var browserSync=require('browser-sync'); gulp.task('serve',function(){ browserSync({ server:{ baseDir:['dist']//设置目录 }, },function(err,bs){ console.log(bs.options.getIn(['urls','local'])); }); //监视文件,当参数1有改变时应该执行参数2任务,每个任务里需要加pipe(browserSync.reload()) gulp.watch('src/styles/*.less',['style']); gulp.watch('src/scripts/*.js',['script']); gulp.watch('src/images/*.*',['image']); gulp.watch('src/*.html',['html']); })
gulp.task(参1,参2)中第一个参数为任务名称,第二个参数为具体要执行的任务描述。要运行gulp任务,只需切换到存放gulpfile.js文件的目录(windows平台请使用cmd或者Power Shell等工具),然后在命令行中执行gulp命令就行了,gulp后面可以加上要执行的任务名,例如gulp style,如果没有指定任务名,则会执行任务名为default的默认任务。
三、gulp基本API
1.gulp.src()
Gulp中,使用的是Nodejs中的stream(流),首先获取到需要的stream,然后可以通过stream的pipe()方法把流导入到你想要的地方,比如Gulp的插件中,经过插件处理后的流又可以继续导入到其他插件中,当然也可以把流写入到文件中。所以Gulp是以stream为媒介的,它不需要频繁的生成临时文件,这也是Gulp的速度比Grunt快的一个原因。再回到正题上来,gulp.src()方法正是用来获取流的,但要注意这个流里的内容不是原始的文件流,而是一个虚拟文件对象流(Vinyl files),这个虚拟文件对象中存储着原始文件的路径、文件名、内容等信息,这个我们暂时不用去深入理解,你只需简单的理解可以用这个方法来读取你需要操作的文件就行了。
2.gulp.dest()
gulp.dest()方法是用来写文件的,要想使用好gulp.dest()这个方法,就要理解给它传入的路径参数与最终生成的文件的关系。gulp的使用流程一般是这样子的:首先通过gulp.src()方法获取到我们想要处理的文件流,然后把文件流通过pipe方法导入到gulp的插件中,最后把经过插件处理后的流再通过pipe方法导入到gulp.dest()中,gulp.dest()方法则把流中的内容写入到文件中,这里首先需要弄清楚的一点是,我们给gulp.dest()传入的路径参数,只能用来指定要生成的文件的目录,而不能指定生成文件的文件名,它生成文件的文件名使用的是导入到它的文件流自身的文件名,所以生成的文件名是由导入到它的文件流决定的,即使我们给它传入一个带有文件名的路径参数,然后它也会把这个文件名当做是目录名。
3.gulp.task()
gulp.task(name[, deps], fn),其中name为任务的名字,如果你需要在命令行中运行你的某些任务,那么,请不要在名字中使用空格。deps为一个包含任务列表的数组,这些任务会在你当前任务运行之前完成。你的任务是否在这些前置依赖的任务完成之前运行了?请一定要确保你所依赖的任务列表中的任务都使用了正确的异步执行方式:使用一个 callback,或者返回一个 promise 或 stream。
该函数定义任务所要执行的一些操作。通常来说,它会是这种形式:gulp.src().pipe(someplugin())
。
注意: 默认的,task 将以最大的并发数执行,也就是说,gulp 会一次性运行所有的 task 并且不做任何等待。如果你想要创建一个序列化的 task 队列,并以特定的顺序执行,你需要做两件事:
- 给出一个提示,来告知 task 什么时候执行完毕,
- 并且再给出一个提示,来告知一个 task 依赖另一个 task 的完成。
对于这个例子,让我们先假定你有两个 task,"one" 和 "two",并且你希望它们按照这个顺序执行:
a.在 "one" 中,你加入一个提示,来告知什么时候它会完成:可以再完成时候返回一个 callback,或者返回一个 promise 或 stream,这样系统会去等待它完成。
b.在 "two" 中,你需要添加一个提示来告诉系统它需要依赖第一个 task 完成。
因此,这个例子的实际代码将会是这样:
var gulp = require('gulp'); // 返回一个 callback,因此系统可以知道它什么时候完成 gulp.task('one', function(cb) { // 做一些事 -- 异步的或者其他的 cb(err); // 如果 err 不是 null 或 undefined,则会停止执行,且注意,这样代表执行失败了 }); // 定义一个所依赖的 task 必须在这个 task 执行之前完成 gulp.task('two', ['one'], function() { // 'one' 完成后 }); gulp.task('default', ['one', 'two']);
4.gulp.watch()
gulp.watch()用来监视文件的变化,当文件发生变化后,我们可以利用它来执行相应的任务。
gulp.watch(glob[,opts],tasks),其中glob为一个字符串或包含多个glob字符串的数组,用来指定具体监控哪些文件的变动。opts一个可选的配置对象,通常不需要用到。tasks为文件变化后要执行的任务,为一个数组。
gulp.watch第三个参数还可以为callback,代表每次变动后需要执行的回调函数,如:
gulp.watch('js/**/*.js', function(event) { console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); }); //callback 会被传入一个名为 event 的对象。这个对象描述了所监控到的变动