安装Gulp官网Gulp4.0将cli和core部分分开,所以这两个包需要单独安装,环境要求如下:n??ode>=8.11.1npm>=5.6。0npx>=9.7.1全局安装gulp-clinpmi-ggulp-cli本地安装gulpnpmi-Dgulp查看版本号$gulp-v#输出CLI版本:2.2.0本地版本:4.0.2配置文件创建gulpfile项目根目录文件中的.js(如果使用ts或者babel,也可以分别替换为gulpfile.ts和gulpfile.babel.js),这个文件就是gulp默认会读取的配置文件,我们可以在其中配置所需的任务。如果任务较多或复杂,可以创建一个gulpfile.js目录,将任务拆分成目录下的多个文件,只要目录下有index.js入口即可。tasktask分为两种:privatetasks:配置文件中的一个函数,只能在本文件中使用publictasks:exportprivatetasks,可以通过gulp命令执行const{series,parallel}=require('gulp');//Privatetasksfunctionclean(cb){//主体省略cb();}//Privatetasksfunctionbuild(cb){//主体省略cb();}exports.build=build;//公共任务,执行gulpbuildexports.default=series(clean,parallel(css,javascript));//公共任务,执行gulp注意:在任务中,当操作完成后,我们必须通过cb()或return通知gulp任务已经完成。//cbfunctionclean(cb){del(['dist]);cb();});//返回函数minifyjs(){returnsrc('src/**/*.js').pipe(minify()).pipe(dest('dist'));});functionpromiseTask(){returnnewPromise(function(resolve,reject){//主体省略resolve();});});runtaskgulpgulp//默认导出的任务可以直接运行gulp组合taskseries:sequence(顺序执行)//task1在执行task2之前执行exports.taskName=series(task1,task2)parallel:parallel(同时执行)//task1与task2同时执行exports.taskName=parallel(task1,task2):exports.taskName=series(clean,parallel(css,javascript))inputandoutputGulp借鉴了Unix的管道(pipe)思想,并使用流来处理文件,这样上一步的输出作为下一步的输入,中间不会将文件写入磁盘,文件只在dest输出,所以它非常快速和高效。Gulp提供了src和dest方法分别进行文件读取和输出操作,也提供了pipe管道方法以链式方式进行其他操作。const{src,dest}=require('gulp');//将src目录下的所有js输出到输出目录exports.default=function(){returnsrc('src/*.js').pipe(dest('output/'));}如果我们想在中间添加文件,可以使用如下方法:const{src,dest}=require('gulp');constuglify=require('gulp-uglify');exports.default=function(){returnsrc('src/*.js').pipe(uglify()).pipe(src('vendor/*.js'))//添加文件.pipe(dest('output/'));}当然我们也可以输出多次:const{src,dest}=require('gulp');constbabel=require('gulp-babel');constuglify=require('gulp-uglify');exports.default=function(){returnsrc('src/*.js').pipe(babel()).pipe(dest('temp/')).pipe(uglify()).pipe(dest('output/'));}文件匹配我们在使用src方法的时候往往需要输入多个或者一种类型的文件,而不仅仅是一个特定的文件,那么我们可以使用匹配gulp提供的规则来处理."src/file.js":单个文件["src/file1,src/file2.js"]:多个文件*:所有文件src('src/*.js')//src自己目录下的所有js文件,excludingsrc('src/a*c.js')**indescendantfolders:0ormorefolderssrc('src/**/*.js')//src目录下的所有js文件,包括{}在descendantfolder:multipleattributessrc('src/*.{jpg,png,gif}')//src自己目录下的所有jpg,png,gif文件!:Excludesrc(['**/*.js','!node_modules/**'])//所有js文件,node_modules下除外注意:src接收到的文件匹配字符串会被顺序解释,所以可以这样写gulp.src(['.js','!b.js','bad.js'])(排除所有b开头的JS文件但bad.js除外)使用插件等库gulp建议每个插件只专注于做一小块工作,并且通过管道连接它们,做我们需要做的。const{src,dest}=require('gulp');constuglify=require('gulp-uglify');constrename=require('gulp-rename');exports.default=function(){returnsrc('src/*.js')//gulp-uglify插件不会更新文件名.pipe(uglify())//所以使用gulp-rename来改变扩展名.pipe(rename({extname:'.min.js'})).pipe(dest('output/'));}当然除了插件,我们还可以使用其他库:constdel=要求('删除');exports.default=function(cb){//直接使用`delete`模块,不用gulp-rimrafdel(['output/*.js'],cb);}最后还可以使用through2插件-in自己内联处理,也可以使用through2来做Gulp插件开发:const{src,dest}=require('gulp');constuglify=require('uglify-js');constthrough2=require('through2');exports.default=function(){returnsrc('src/*.js')//除了使用gulp-uglify,你可以创建一个内联插件.pipe(through2.obj(function(file,_,cb){如果(file.isBuffer()){常量代码=uglify.minify(file.contents.toString())file.contents=Buffer.from(code)}cb(null,file);})).pipe(dest('output/'));}监控文件我们可以使用watch方法来监控文件变化,这样当变化时执行相应的处理任务const{watch,series}=require('gulp');functionclean(cb){//主体省略cb();}functionjavascript(cb){//主体省略cb();}functioncss(cb){//主体省略cb();}exports.default=function(){watch('src/*.css',css);watch('src/*.js',series(clean,javascript));};APIsrc(globs,[options]):输入globs[string|array]:待处理文件的路径匹配规则options:配置项,点击查看详情const{src,dest}=require('gulp');functioncopy(){returnsrc('input/*.js',{sourcemaps:true}).pipe(dest('output/'));}dest(directory,[options]):输出目录[字符串|函数]:outputPathoptions:配置项,点击查看详情const{src,dest}=require('gulp');constuglify=require('gulp-uglify');src('input/**/*.js',{sourcemaps:true}).pipe(uglify()).pipe(dest('output/',{sourcemaps:'.'}));series(...tasks):按顺序执行多个任务tasks[function|string]:tasknameorfunctionconst{series}=require('gulp');functionjavascript(cb){//body省略cb();}functioncss(cb){//主体省略cb();}exports.build=series(javascript,css);parallel(...tasks):多个任务同时执行{//主体省略cb();}functioncss(cb){//主体省略cb();}exports.build=parallel(javascript,css);watch(globs,[options],[task]):filewatchglobs[string|array]:要监控的文件options:配置项,点击查看详情task[function|string]:要执行的任务或操作const{watch}=require('gulp');watch(['input/*.js','!input/something.js'],function(cb){//主体省略cb();});监听方法会返回一个total实例,提供了以下方法:watcher.on(eventName,eventHandler)eventName[string]:事件名称,可以是add,addDir,change,unlink,unlinkDir,ready,error,alleventHandler[function]:事件处理函数,接收path和stats两个参数const{watch}=require('gulp');constwatcher=watch(['input/*.js']);watcher.on('change',function(path,stats){console.log(`File${path}waschanged`);});watcher.on('add',function(path,stats){控制台。log(`File${path}wasadded`);});watcher.on('unlink',function(path,stats){console.log(`File${path}wasremoved`);});watcher.close();watcher.close():关闭文件侦听器watcher.add(globs):将文件添加到观察器globs[string|array]:要添加的文件watcher.unwatch(globs):从观察器globs中删除文件[string|array]:filestoremovetask([taskName],taskFunction):Definetask(4.0推荐使用function而不是这种方式)taskName[string]:任务名称taskFunction[function]:处理函数const{task}=require('吞咽');task('build',function(cb){//主体省略cb();});constbuild=task('build');lastRun(task,[precision]):获取任务最后一次运行的时间戳task[function|string]:指定获取任务的precision[number]:precision,default1000此方法可用于增量编译。const{src,dest,lastRun,watch}=require('gulp');constimagemin=require('gulp-imagemin');functionimages(){returnsrc('src/images/**/*.jpg',{since:lastRun(images)}).pipe(imagemin()).pipe(dest('build/img/'));}exports.default=function(){watch('src/images/**/*.jpg',images);};tree([options]):获取任务依赖options[object]:deep默认为false,只返回顶层任务,如果为真,则返回整个任务树。gulp.tree({deep:true})vinyl:文件描述符,具体使用可能需要自己开发插件,看gulp源码分析(二)——vinyl-fs这些是我经常用到的api,等其他api都可以用自己查看官方文档。常用插件gulp-clean:用于清理;gulp-notify:用于打印消息文本;gulp-rename:用于修改名称;gulp-concat:用于合并文件;gulp-zip:用于生成zip存档;gulp-minify-css:用于压缩css;gulp-autoprefixer:用于给css添加前缀;gulp-imagemin:用于优化图像;gulp-uglify:用于压缩js;amd-optimize:用于amd模块参考编译;gulp-import-css:如果通过import导入css文件,可以使用该插件进行合并优化;gulp-rev-replace:用于替换;gulp-useref:导入并使用构建标签进行替换;gulp-rev:生成md5文件名;gulp-filter:过滤文件;gulp-header:压缩后在文件头部写注释gulp-if:进行逻辑判断gulp-size:获取文件大小gulp-less:编译less文件gulp-sass:编译sass文件gulp-file-include:导入文件gulp-sourcemaps:生成地图文件gulp-livereload:自动刷新gulp-clean-css:css压缩browserSync:启动服务器,开始热更新gulp-plumber:监控工作流,报错,防止直接退出gulp-rev:添加版本numbertofilenamegulp-css-spritesmith:根据css文件自动生成sprite图片如果想找gulp插件,一般有两个地方:官方插件库汇总npm仓库:gulp本身其实很简单,API少,但足够简洁。了解了这些API之后,你可能会发现最复杂的是了解各个插件的用法。其实构建工具(gulp、webpack等)本身就比较简单,本该如此,本身就很复杂,懒得用了。但是在使用的过程中,我觉得有两个难点:如何制定一套合理的、可配置的、真正能提高我们工作效率的构建流程,如何在某个功能出现时快速找到最合适的插件需要的,能够快速使用最后,本人见识浅薄,如有不妥之处,还望指正。