前言

这篇文章本应该在去年17年写的,但因为种种原因没有写,其实主要是因为懒(捂脸)。gulp出来的时间已经很早了,16年的时候还很流行,到17年就被webpack

碾压下去了,不过由于本人接触gulp的时候比较晚,16年的时候才听说有这么个玩意,正真用它是在17年的时候,但是虽然现在webpack已经大行其道,我们每个人都

在积极去拥抱它,不过gulp在现在来说也并不是一无是处,还是有用到的地方,所以,这篇文章我觉得还有有必要写的,就当做是为gulp写的最后一篇文章吧 ,做技术就是

这么辛苦,技术更新太快,2,3年的时间就要换一拨技术,又得学习新的东西,不然面对这么激烈的市场,就得被淘汰。废话不多说了,下面开始正文。

gulp是什么,能做什么

gulp是一个前端自动化流程构建工具,诸如,css,js,图片合并压缩,less,sass编译,以前我们需要手工才能完成的工作,现在只要通过gulp并结合gulp插件就可以轻松的处理这些操作,极大的节省了开发时间,优化开发流程,提供生产效率。它跟gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,提供的API非常简单,学习起来也很容易,另外,gulp是基于nodejs,是通过stream流的形式来读取和操作数据,速度方面更快。

gulp API

1、gulp.src()

输出(Emits)符合所提供的匹配模式(glob)或者匹配模式的数组(array of globs)的文件。 将返回一个 Vinyl files 的 stream 它可以被 piped 到别的插件中。

gulp.src('client/templates/*.jade')

.pipe(jade())

.pipe(minify())

.pipe(gulp.dest('build/minified_templates'));

2、gulp.dest()

能被 pipe 进来,并且将会写文件。并且重新输出(emits)所有数据,因此你可以将它 pipe 到多个文件夹。如果某文件夹不存在,将会自动创建它。

gulp.src('./client/templates/*.jade')

.pipe(jade())

.pipe(gulp.dest('./build/templates'))

.pipe(minify())

.pipe(gulp.dest('./build/minified_templates'));

3、gulp.task()

定义一个使用 Orchestrator 实现的任务(task)。

gulp.task('somename', function() {

// 做一些事

});

4、gulp.watch()

监视文件,并且可以在文件发生改动时候做一些事情。它总会返回一个 EventEmitter 来发射(emit) change 事件。

var watcher = gulp.watch('js/**/*.js', ['uglify','reload']);

watcher.on('change', function(event) {

console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');

});

整理的一些gulp插件

一、必备插件,一些基础插件

gulp-htmlmin 看到名字就能知道,这个插件是用来压缩 HTML。PS:注释啥的都可以去掉哦,看文档get更多技能哈

gulp-imagemin 除了能压缩常见的图片格式,还能压缩 SVG,叼叼的~

gulp-clean-css 压缩 CSS。我原本推荐的是 gulp-minify-css,结果其首页中已建议改用gulp-clean-css...

gulp-uglify 专业压缩 Javascript

gulp-concat 上面几个都是压缩,这插件是管合并的...恭喜,“减少网络请求”的成就达成:)

gulp-autoprefixer 给 CSS 增加前缀。解决某些CSS属性不是标准属性,有各种浏览器前缀的情况,灰常有用

gulp-rename 修改文件名称。比如有时我们需要把app.js改成app.min.js,瞬间高级了

gulp-util 最基础的工具,但俺只用来打日志...

二、常用插件,一些有用的插件,但使用场景和频率没那么高的好插件

run-sequence gulp 的 task 都是并行(异步)执行,如果遇见需要串行的场景,那么这个插件就是必备了。偶的使用场景是:处理(压缩、合并等等) CSS/JS、再gulp-rev、再上传 CDN;然后使用 CDN的地址替换 HTML 中的 CSS/JS 地址,再压缩 HTML。那么替换 HTML 这步须在之前的工作处理完后再执行。 ** 最后要说,gulp4.0发布后,不需要RS也可以搞定串行任务了 **

del / gulp-clean 删除。俺的使用场景是:JS/CSS 文件都会在压缩后使用gulp-rev,即文件名被hash,然后再上传到 CDN,最后俺再使用 删除插件 把本地压缩后的文件删除掉,不用多余保存。

gulp-rev 把静态文件名改成hash的形式。

gulp-rev-replace 配合 gulp-rev 使用,拿到生成的 manifest。json 后替换对应的文件名称。

gulp-rev-collector 到线上环境前,我会用来配合gulp-rev使用,替换 HTML 中的路径

gulp-rev-append 给页面引用的静态文件增加hash后缀,避免被浏览器缓存...当然,如果是使用 CDN,这个套路就不行了

gulp-connect / gulp-livereload LiveReload 的俩款插件都值得拥有,不过都各稍有学习成本,看看文档就明白鸟

gulp-sourcemaps 处理 JavaScript 时生成 SourceMap;如果你不了解 SourceMap,可以看看这篇阮一峰大神的《Source Map 详解》

gulp-load-plugins 帮忙偷懒用的,可以帮我们加载插件,不用require或者import...当然,俺个人感觉用了这个插件后,阅读gulpfile.js的可读性差了,鱼和熊掌不可兼得:(

gulp-jshint JavaScript 代码校验

gulp-sass / gulp-less 写 CSS 的同学都懂哈

三、进阶插件,根据业务场景的不同,我们可能会用到这些插件

babel JS 语法新特性用起来。这个插件可以让我们用新的 标准/特性/提案 写 JavaScript 代码,然后再向下 转换编译,最终生成随处可用的 JavaScript 代码。更通俗的说话就是:可以用新的规范写代码,经过 babel 编译后生成没有兼容问题的代码。

gulp-flatten 移动指定文件,不想压缩或者合并的时候,直接用这个插件把对应文件移动到指定文件夹。俺偶尔在内部项目会偷懒用上,图方便:)

gulp-coffee CoffeeScript 值得去了解

gulp-markdown-pdf 把 Markdown 编译为 PDF

gulp-markdown 写手的福音,可以把 Markdown 转成 HTML

gulp-html2md 把 HTML 编译为 Markdown

gulp-tinypng 超屌的图片压缩工具,使用 Tinypng 引擎。PS:因为 Tinypng 免费帐号有月限制,所以使用使需注意。

sprity 生成雪碧图。稍有点学习成本,仔细阅读文档即可。

gulp-if 可以在 pipe 里面写点逻辑了,屌不屌。举例:比如处理 ./pub/*.js,如果文件名称是 xxx.js,那么不处理;更可以用来区分当前是开发环境还是生产环境。

gulp-file-include 俺搞内部项目的时候会用到,让 HTML 组件化的第一小步

gulp-git 直接在 Build 时把代码都提交到 git上了...特么劳资懒起来连我自己都害怕

gulp-qiniu 用于把指定文件上传至七牛的指定路径下(PS:首先,你得有自己的七牛账号和空间)

gulp-notify 在控制台中加入文字描述,build 的时候更高级有木有。当然,当需要的时候把错误信息也展示出来会很有帮助。更高级的功能就需要你查看其文档了~

gulp-plumber gulp 的错误处理有点坑,假如发生错误进程就挂了。相对的解决办法不少,但是这个是我个人比较推荐的,比特么在容易出错的地方写错误监听靠谱。所以这个插件可以阻止 gulp 插件发生错误导致进程退出并输出错误日志。

gulp的使用

1、在项目根目录下创建一个名为 gulpfile.js 的文件

var gulp = require('gulp');

gulp.task('default', function() {

console.log("执行第一个gulp任务")

});

输入gulp命令执行该任务,不指定任务名称 则默认执行default任务

2、同时执行多个任务

gulp.task('n1',function(){

console.log("执行任务n1")

});

gulp.task('n2',function(){

console.log("执行任务n2")

});

gulp.task('N',['n1','n2']);

3、如果有2个任务存在依赖关系,如任务A依赖任务B,在B任务执行完成之后再执行A任务

gulp.task('B',function(){

console.log("执行任务B")

});

gulp.task('A',['B'],function(){

console.log("任务B执行完成之后,开始执行任务A")

});

4、通过gulp.watch监听文件变化,这里新建一个watch task任务,用gulp.watch来监听index.html文件,执行该task任务

gulp.task('watch',function(){

gulp.watch('./src/index.html').on('change', function(event) {

console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');

});

});

修改index.html文件,可以看到控制台输出以下内容,event.type输出的是changed,除此之外还有added, deleted类型

5、编译less

这里使用gulp-less插件

安装 npm install --save-dev gulp-less

var less = require("gulp-less");

gulp.task('less',function(){

console.log("开始编译less...")

gulp.src('./src/less/index.less')

.pipe(less())

.pipe(gulp.dest('./src/css'));

console.log("less编译完成");

});



可以看到自动为我们生成了一个index同名css文件

使用gulp-postcss和autoprefixer 插件处理浏览器前缀,解决浏览器兼容性问题,不必手动添加css前缀,并且支持soucemap

安装

npm install gulp-postcss --save-dev

npm install autoprefixer --save-dev

npm install gulp-sourcemaps --save-dev

var less = require("gulp-less");

var postcss = require('gulp-postcss');

var sourcemaps = require('gulp-sourcemaps');

var autoprefixer = require('autoprefixer');

gulp.task('less',function(){

console.log("开始编译less...")

gulp.src('./src/less/index.less')

.pipe(less())

.pipe(sourcemaps.init())

.pipe(postcss([autoprefixer()]))

.pipe(sourcemaps.write('.'))

.pipe(gulp.dest('./src/css'));

console.log("less编译完成");

});

修改less文件添加以下样式:

.win{transform: translateX(-50%);}

执行编译less任务,可以看到index.css文件自动为transform添加了浏览器前缀



同时也为我们生成了一个map格式文件

6、watch监听less文件变化,自动执行less编译任务

gulp.task('watch',function(){

gulp.watch(['./src/less/index.less'],['less']);

});

当修改less文件并保存时,看到less文件已经编译完成了

7、使用broswer-sync自动刷新浏览器

安装

npm install browser-sync --save-dev

// 静态服务器 + 监听 less/html 文件

var browserSync = require('browser-sync').create();

gulp.task('browser-sync',['less'],function(){

browserSync.init({

server: {

baseDir: "./src" // 从这个项目的src目录启动服务器

}

});

gulp.watch(['./src/less/index.less'],['less']);//监听less文件

gulp.watch("src/*.html").on('change', browserSync.reload);//监听html文件变化 自动刷新浏览器

});

最后,修改html文件并保存,可以看到浏览器自动刷新了

less+css浏览器注入

在less任务后面添加以下代码,将less编译后的css注入到浏览器里实现更新,换句话说就是我们修改less文件后编译完成后的css反应到浏览器页面中

.pipe(browserSync.reload({stream: true}));

添加以上代码后,但发现还是无法实现刷新 ,这里如果我们编译less使用了sourcemap,则无法刷新,可以通过gulp-filter来解决。

安装:

npm install gulp-filter --save-dev

修改编译less的任务,添加红色部分内容即可

8、使用gulp-clean-css压缩css文件并重命名

安装:

npm install gulp-clean-css --save-dev

npm install gulp-rename --save-dev

// 压缩css文件并重命名

var cleanCSS = require('gulp-clean-css');

var rename = require("gulp-rename");

gulp.task('minify-css',function(){

gulp.src('./src/css/*.css')

.pipe(rename({suffix: '.min'})) //suffix添加后缀 其他的还有prefix , extname等

.pipe(cleanCSS())

.pipe(gulp.dest('./src/css'));

});

执行该task,可以看到生成了index.min.css压缩文件

9、为我们的css文件MD5命名 并且在引用的文件路径替换

主要用到 gulp-rev 和gulp-rev-collector这两个插件

安装

npm install gulp-rev --save-dev

npm install gulp-rev-collector --save-dev

// 压缩css文件并重命名

// md5文件命名 引用路径替换

var cleanCSS = require('gulp-clean-css');

var rename = require("gulp-rename");

var rev = require('gulp-rev'); //- 对文件名加MD5后缀

var revCollector = require('gulp-rev-collector'); //- 路径替换

gulp.task('minify-css',function(){

console.log('开始压缩css文件')

return gulp.src('./src/css/*.css')

.pipe(rename({suffix:'.min'})) //文件重命名 suffix添加后缀 其他的还有prefix , extname等

.pipe(cleanCSS()) //压缩处理

.pipe(rev()) //- 文件名加MD5后缀

.pipe(gulp.dest('./src/css')) //- 输出文件本地

.pipe(rev.manifest()) //- 生成一个rev-manifest.json 后面的文件路径替换依据此文件内容

.pipe(gulp.dest('./rev')); //- 将 rev-manifest.json 保存到 rev 目录内

console.log('css压缩完成...')

});

gulp运行 minify-css任务,可以看到生成了md5命名的css压缩文件

执行压缩之前先删除文件

del和gulp-clean插件 都是用于清空文件,del可以用于替代gulp-clean,不推荐使用gulp-clean了

安装

npm install del --save-dev

// clean任务:在执行压缩之前先clean

var del = require('del');

gulp.task('clean',function(cb){

return del(['./dist']);

})

10、使用gulp-sequence插件处理同步任务

run-sequence gulp 的 task 都是并行(异步)执行,如果遇见需要串行的场景,那么这个插件就是必备了。偶的使用场景是:处理(压缩、合并等等) CSS/JS、再gulp-rev、再上传 CDN;然后使用 CDN的地址替换 HTML 中的 CSS/JS 地址,再压缩 HTML。那么替换 HTML 这步须在之前的工作处理完后再执行。 ** 最后要说,gulp4.0发布后,不需要RS也可以搞定串行任务了 **

执行前端代码自动构建,一般会分为以下几个步骤

1. 清理目标目录(任务:clean)

2. 代码压缩打包,这其中包括对JS,CSS,HTML以及图片的处理(任务:minify:js,minify:css,minify:html,minify:image)

3. 监控(任务:watch)

安装

npm install --save-dev run-sequence

// 同步执行任务

var runSequence = require('run-sequence');

gulp.task('build', function() {

runSequence('rev');

});

11、javascript代码压缩

gulp-uglify

安装

npm install gulp-uglify --save-dev

var uglify = require('gulp-uglify');

gulp.task('minify-js',function(){

gulp.src('src/js/*.js')

.pipe(uglify())

.pipe(gulp.dest('dist/js'));

});

压缩之后代码:

12、html代码压缩

gulp-htmlmin

安装

npm install gulp-htmlmin --save-dev

var htmlmin = require('gulp-htmlmin');

gulp.task('minify-html', function() {

return gulp.src('src/*.html')

.pipe(htmlmin({collapseWhitespace: true}))

.pipe(gulp.dest('dist'));

});

压缩之后代码:

13、图片压缩(包括PNG、JPEG、GIF和SVG图片)

gulp-imagemin

安装

npm install gulp-imagemin --save-dev

gulp.task('minify-img', function() {

return gulp.src('src/images/*.{png,jpg,gif,ico}')

.pipe(imagemin())

.pipe(gulp.dest('dist/images'));

});

压缩之前大小



压缩之后大小

其他参数

var imagemin = require('gulp-imagemin');

gulp.task('minify-img', function() {

return gulp.src('src/images/*.{png,jpg,gif,ico}')

.pipe(imagemin({

optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级)

progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片

interlaced: true, //类型:Boolean 默认:false 隔行扫描gif进行渲染

multipass: true //类型:Boolean 默认:false 多次优化svg直到完全优化

}))

.pipe(gulp.dest('dist/images'));

});

14、js代码合并,减少http请求数量

gulp-concat

安装

npm install gulp-concat --save-dev

var concat = require('gulp-concat');

gulp.task('jsconcat', function () {

gulp.src('src/js/*.js')

.pipe(concat('main.js'))//合并后的文件名

.pipe(gulp.dest('dist/js'));

});

坑记录

1、在编写less文件时报以下这个错误,发现是因为我sublime安装了less2css这个插件

首选项-》pageage setting找到less2css,发现default设置autocompile是true自动编译

修改user设置将autoCompile设置为false即可

{

"autoCompile": true

}

2、在压缩css文件时,生成格式有问题

在压缩之前先清空目标文件

3、关于gulp的gulp-clean-css压缩插件参数问题

这是告诉cleancss压缩时要不要保留IE8及以下兼容写法,写compatibility:'ie7'就是保留ie7兼容写法。。比如zoom:1;这些,不保留它就给你删除了。。

压缩插件不仅仅是压缩,还能优化,如果你用gulp-cssnano,还能帮你把多余的类名和属性合并。。等等

4、gulp中的return

在gulp这里,返回的是gulp.src这个对象,以便接下来的回调(如果有的话)能继续调用这个gulp.src对象,完成其他的事情。

task的回调函数必须得有返回值

return a promise or event stream。否则程序就相当于同步的

当任务有返回以上返回值时,则任务会按一定的顺序执行。

5.在开启静态服务器模式下,监听文件变化,如果执行clean删除任务会报以下错误

在开发环境,静态服务器模式下,不要执行clean任务

最后

总结一下,本文从gulp是什么,gulp能做什么出发,对gulp简单的介绍了一下,包括gulp提供的一些API,然后整理并罗列了一些开发中常用到的gulp插件,

最后,就是从gulp安装到使用详细介绍了gulp的用法,以及使用gulp插件来构建前端自动化的开发流程。

相关资料

https://www.gulpjs.com.cn/

https://www.cnblogs.com/2050/p/4198792.html

https://www.cnblogs.com/Darren_code/p/gulp.html

https://www.cnblogs.com/2050/p/4198792.html

https://blog.csdn.net/mjzhang1993/article/details/68485085

作者:fozero

声明:原创文章,转载请注明出处,谢谢!http://www.cnblogs.com/fozero/p/7770206.html

标签:gulp

一篇迟到的gulp文章的更多相关文章

  1. 一篇迟到的gulp文章,代码合并压缩,less编译

    前言 这篇文章本应该在去年17年写的,但因为种种原因没有写,其实主要是因为懒(捂脸).gulp出来的时间已经很早了,16年的时候还很流行,到17年就被webpack 碾压下去了,不过由于本人接触gul ...

  2. 《转载-两篇很好的文章整合》Android中自定义控件

    两篇很好的文章,有相互借鉴的地方,整合到一起收藏 分别转载自:http://blog.csdn.net/xu_fu/article/details/7829721 http://www.cnblogs ...

  3. (转)干货|这篇TensorFlow实例教程文章告诉你GANs为何引爆机器学习?(附源码)

    干货|这篇TensorFlow实例教程文章告诉你GANs为何引爆机器学习?(附源码) 该博客来源自:https://mp.weixin.qq.com/s?__biz=MzA4NzE1NzYyMw==& ...

  4. 给B公司的一些建议(又一篇烂尾的文章)

    感慨:太多太多的悲伤故事,发生在自己身上,发生在自己的身边.因此,为了避免总是走"弯路",走"错误"的道路,最近一直在完善自己的理论模型. 烂尾说明:本文是一篇 ...

  5. 小鹏汽车技术中台实践 :微服务篇 InfoQ 今天 以下文章来源于InfoQ Pro

    小鹏汽车技术中台实践 :微服务篇 InfoQ  今天 以下文章来源于InfoQ Pro

  6. 转一篇dudu大人的文章:程序员,用NuGet管理好你的包包

    每个女人都有很多包包:其实男人也有,但只有会写程序的男人才有 —— 代码世界中的大“包”小“包”.这些大包小包,有花钱买的,有从开源市场淘的,也有自己或同事亲手制作的. 包包有个特点:容易坏,更新快, ...

  7. 转帖一篇sixxpack破解的文章!

    星期天闲着没事玩游戏,玩游戏不能无外挂.于是百度了半天,找到了一个,看介绍貌似不错,就下载了下来.一看,竟然是用.net写的,下意识地Reflector了一下.发现竟是一个叫actmp的程序集.如图: ...

  8. 关于ssh的一篇很好的文章

    源地址:http://www.w3hacker.com/?p=156   ssh-agent的manual写得倒是挺详细,可看了好几次都没怎么搞明白.08年在网上找到了非常好的一篇文章,An Illu ...

  9. Mybatis分页插件PageHelper正确的用法(网上有2篇不够科学的文章)

    今天下午在Mybatis项目中.实现分页.由于我是后加入项目中的,Leader用的是PageHelper这个组件.可是我在实际使用的过程中遇到了2个大问题. 1.p=2#comments" ...

随机推荐

  1. xml特殊字符处理 如&

     写了个request2XML的方法,每当数据中有'<'.'&'符号时,封装的XML就无法解析.发现了XML里的CDATA属性,问题迎刃而解!在XML文档中的所有文本都会被解析器解析 ...

  2. Android 文件操作心得体会

    android 的文件操作说白了就是Java的文件操作的处理.所以如果对Java的io文件操作比较熟悉的话,android的文件操作就是小菜一碟了.好了,话不多说,开始今天的正题吧. 先从一个小项目入 ...

  3. Oracle Apps DBA 常用命令

    数据库启动监听 addlnctl.sh start instance 启动数据库 addbctl.sh start 启动应用服务器 adstrtal.sh 停止应用服务器 adstpall.sh -- ...

  4. UNIX环境高级编程——system函数

    system函数 功能:调用fork产生子进程,由子进程来调用:/bin/sh -c command来执行参数command所代表的命令,阻塞当前进程直到command命 令执行完毕. int sys ...

  5. 02_Weblogic课程之安装篇:RedHat下JDK安装,RedHat下Weblogic安装,目录结构,环境变量设置

     1  Weblogic的安装方式有三种: 一.GUI方式安装    (java –jar wls1035_generic.jar [-mode=gui])这是默认的 二.Console方式安装  ...

  6. ad network 和 ad exchange 的对比

    著名的SSP技术提供商PubMatic联合四家知名的DSP公司跟踪实时竞价系统的效果,给出的结果是惊人的749%广告效果提升和64%的媒体收入的增加.2007年发生的一系列在广告交易领域的创投,以及一 ...

  7. XBMC源代码分析 6:视频播放器(dvdplayer)-文件头(以ffmpeg为例)

    XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 XBMC源代码分析 4: ...

  8. SpriteBuilder中CCMotionStreak提示图片文件找不到

    今天写代码时遇到上述问题,代码如下: player.streak = [CCMotionStreak streakWithFade:3.f minSeg:1 width:30 color:[CCCol ...

  9. AngularJS进阶(三十一)AngularJS项目开发技巧之获取模态对话框中的组件ID

    AngularJS项目开发技巧之获取模态对话框中的组件ID 需求 出于项目开发需求,需要实现的业务逻辑是:药店端点击查看"已发货""已收货"订单详情时,模块弹出 ...

  10. 【一天一道LeetCode】#46. Permutations

    一天一道LeetCode系列 (一)题目 Given a collection of distinct numbers, return all possible permutations. For e ...