Gulp 学习笔记
Posted 最骚的就是你
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gulp 学习笔记相关的知识,希望对你有一定的参考价值。
参考:http://www.cnblogs.com/tugenhua0707/p/4069769.html
Gulp实现web服务器
阅读目录
一:gulp实现web服务器配置:
对于前端开发而言,需要在本地搭建一个服务器作为开发使用,虽然有时候也可以直接打开页面进行预览效果,但是有时候页面需要在服务器运行,以前的做法是下载一个php,直接安装下即可,或者使用nodeJS作为web服务器,今天我门可以来学习下使用gulp的一个插件 gulp-connect来配置作为本地服务器来使用;当然该插件也是居于nodeJS环境中的。
一:gulp实现web服务器配置:
初始化安装
首先,使用下面的命令来安装connect插件。
sudo npm install --save-dev gulp-connect
因此package.son内容代码变为如下:
{ "name": "tongbanke", "version": "1.0.0", "description": "tobanke\'", "main": "main.js", "scripts": { "test": "test" }, "repository": { "type": "git", "url": "gulp" }, "keywords": [ "gulp", "test" ], "author": "kongzhi", "license": "ISC", "devDependencies": { "gulp": "^3.6.2", "gulp-connect": "^2.0.5" } }
gulpfile.js代码如下
var gulp = require(\'gulp\'), connect = require(\'gulp-connect\'); gulp.task(\'webserver\', function() { connect.server(); }); gulp.task(\'default\', [\'webserver\']);
如上是package.son代码和gulpfile.js代码;我们可以直接复制下来,新建package.son和gulp file.js两个文件,然后进入项目的目录下 npm install 即可把所有的依赖包加载出来。如下图:
这样就好了,然后我们在终端命令下运行gulp命令即可;如下所示:
然后我们在浏览器中打开 localhost:8080/index.html 就可以看到内容了,gulpfile.js文件是在网站的根目录下,服务器将一直运行,监听localhost:8080,如果我们想要停止服务器的话,可以回到中断命令下按ctrl+c键即可。这个demo我也放到了github上了,如下:
https://github.com/tugenhua0707/basic
我们可以直接使用git把它克隆下来放在本地目录下,然后进入该目录下,使用终端命令
npm install 即可,把所有的依赖包就能提取出来。再运行gulp命令后,在浏览器下运行
http://localhost:8080/即可看到index.html页面了。
二:添加实时刷新(livereload)支持
上面我们已经完成了使用 gulp-connect 实现服务器了,现在我们需要实现实时刷新,这样的话,每当我更改一个文件的时候,我就不需要重新运行命令,直接保存代码即可生效,因此我们现在需要做两件事情:
1. 让web服务器带实时刷新支持启动。
2. 告诉组建什么时候应该自动刷新。
第一步的实现很简单:只要给connect.server()方法传入一个参数即可:
{livereload: true}即可,如下图所示:
对于第二步,我们这里简单的实现以下使用gulpfile.js 来监听less文件,自动把less文件编译成css文件,并将其注入到浏览器中,为了编译LESS文件,我门需要使用到gulp-less 插件,我门可以运行如下命令:
sudo npm install --save-dev gulp-less 来安装gulp-less,并且在gulpfile.js文件中添加这个依赖项,现在我门可以看下 package.json代码变为如下:
// package.son { "name": "tongbanke", "version": "1.0.0", "description": "tobanke\'", "main": "main.js", "scripts": { "test": "test" }, "repository": { "type": "git", "url": "gulp" }, "keywords": [ "gulp", "test" ], "author": "kongzhi", "license": "ISC", "devDependencies": { "gulp": "^3.6.2", "gulp-connect": "^2.0.5", "gulp-less": "^1.2.3", "gulp-coffee": "^1.4.2", "gulp-watch": "^0.6.2" } }
gulpfile.js代码变为如下:
// gulpfile.js // 定义依赖项 var gulp = require(\'gulp\'), connect = require(\'gulp-connect\'), less = require(\'gulp-less\'); // 定义 webserver 任务 gulp.task(\'webserver\', function() { connect.server({ livereload: true }); }); // 定义 less 任务 gulp.task(\'less\', function() { gulp.src(\'styles/main.less\') .pipe(less()) .pipe(gulp.dest(\'styles\')) .pipe(connect.reload()); }); // 定义 watch 任务 gulp.task(\'watch\', function() { gulp.watch(\'styles/*.less\', [\'less\']); }) // 定义默认任务 gulp.task(\'default\', [\'less\', \'webserver\', \'watch\']);
我门再来看看我门现在的目录结构如下:
如上gulpfile.js文件,我门使用watch这个任务去监听LESS文件,每当该文件发生改变的时候,我门都会对less这个任务进行编译,然后把编译的文件写入到目标文件中,因此当我门回到终端命令下运行gulp命令后,每当我门的css文件有更改的话,都可以实时监听到,对于第二点监听到话,gulp有gulp-watch这个插件了,其实可以做的更好的;同样,为了大家有源代码的话,也把项目放入git里面去,大家也可以把它git 克隆下来,自行运行即可:如下:
https://github.com/tugenhua0707/livereload
想学习gulp的watch插件和压缩及合并代码的话,可以看如下文章即可:
http://www.cnblogs.com/tugenhua0707/p/4069769.html
Grunt一直是前端构建工具,然而他也不是毫无缺陷的,gulp的作者 Eric Schoffstall 在他介绍 gulp.js 的 presentation 中总结了 Grunt 的几点不足之处:
- 插件很难遵守单一职责。因为 Grunt 的 API 设计缺憾,使得许多插件不得不负责一些和其主要任务无关的事情。比如说要对处理后的文件进行更名操作,你可能使用的是
uglify
插件,也有可能使用的是concat
插件(取决于工作流的最后一个环节是谁)。 - 用插件做一些本来不需要插件来做的事情。因为 Grunt 提供了统一的 CLI 入口,子任务由插件定义,由 CLI 命令来调用执行,因此哪怕是很简单的外部命令(比如说运行
karma start
)都得有一个插件来负责封装它,然后再变成 Grunt CLI 命令的参数来运行,多此一举。 - 试图用配置文件完成所有事,结果就是混乱不堪。规模较大,构建/分发/部署流程较为复杂的项目,其
Gruntfile
有多庞杂相信有经历的人都有所体会。而 gulp.js 奉行的是“写程序而不是写配置”,它走的是一种 node way。 - 落后的流程控制产生了让人头痛的临时文件/文件夹所导致的性能滞后。这是 gulp.js 下刀子的重点,也是本标题里“流式构建”所解决的根本问题。流式构建改变了底层的流程控制,大大提高了构建工作的效率和性能,给用户的直观感觉就是:更快。
Gulp相对于Grunt有五大优势:
1. 使用 gulp.js,你的构建脚本是代码,而不是配置文件;
2. 使用标准库(node.js standard library)来编写脚本;
3. 插件都很简单,只负责完成一件事.
4. 任务都以最大的并发数来执行;
5. 输入/输出(I/O)是基于“流式”的。
下面我们先来看看在项目中如何使用Gulp来构建项目的吧!在构建之前,我们先来安装下Gulp。
一:Gulp安装-命令行工具。全局安装gulp 命令:npm install -g gulp 如下:
如上,说明gulp已经安装完成!
二:项目demo演示
1. 进入项目gulp的根目录下,如下所示:
如上,是我项目gulp文件。
1. 在项目的根目录下看有没有package.json,如果没有的话,我们需要运行下命令 npm init, 如下所示:
之后在项目跟路径下生产package.json文件.
2. 在项目文件gulp下安装为开发的依赖组件,运行命令:npm install --save-dev gulp 如下所示:
运行完成后,在根目录下生产node_modules文件,如下所示:
3. 在项目的跟路径下新建Gulpfile.js,如下所示:
我们可以给Gulpfile.js的初始内容为:
var gulp = require(\'gulp\');
gulp.task(\'default\', function () {});
4. 运行gulp命令,如下所示:
上面是最基本的运行操作,下面我们来看一个具体的demo吧,还是如上的项目gulp文件,我们现在的需求是想把gulp项目文件下的src所有js文件合并到dist目录下的build.js,压缩后的文件为build-min.js。
在这之前,我们需要安装如下插件:
1. 语法检查(gulp-jshint).
2. 合并文件(gulp-concat).
3. 压缩代码(gulp-uglify).
一:语法检查 运行命令:npm install gulp-jshint --save-dev 如下图所示:
二:合并文件 运行命令:npm install gulp-concat --save-dev 如下图所示:
三:压缩代码 运行命令:npm install gulp-uglify --save-dev 如下图所示:
插件装完成后,我们可以看看根目录下多了几个插件,如下所示:
其中gulp-rename我们去掉,不要的。
四:在项目的根目录下创建Gulpfile.js文件,内容如下:
var gulp = require(\'gulp\'); var jshint = require(\'gulp-jshint\'); var concat = require(\'gulp-concat\'); var uglify = require(\'gulp-uglify\'); // 语法检查 gulp.task(\'jshint\', function () { return gulp.src(\'src/*.js\') .pipe(jshint()) .pipe(jshint.reporter(\'default\')); }); // 合并文件之后压缩代码 gulp.task(\'minify\', function (){ return gulp.src(\'src/*.js\') .pipe(concat(\'build.js\')) .pipe(gulp.dest(\'dist\')) .pipe(uglify()) .pipe(rename(\'build.min.js\')) .pipe(gulp.dest(\'dist\')); }); // 监视文件的变化 gulp.task(\'watch\', function () { gulp.watch(\'src/*.js\', [\'jshint\', \'minify\']); }); // 注册缺省任务 gulp.task(\'default\', [\'jshint\', \'minify\', \'watch\']);
最后在命令行下,运行gulp命令即可。如下所示:
现在我们回到目录下,可以看到如下所示:
如上Gulpfile.js,我们可以看到,基本上所有的任务都是这个模式。
gulp.task(“任务名称”,function(){
return gulp.src(“文件”)
.pie(…)
.pie(….)
})
获取要处理的文件,传递给下一个环节处理,然后把返回的结果继续传给下一个环节,直到所有环节结束,pipe就是stream模块里负责传递流数据的方法而已。
下面我们来看看gulp简单的API,如下:
1. gulp.task(name[,deps],fn) 注册任务。
name: 是任务名称,deps是可选的数组,列出需要在本任务运行要执行的任务,fn是任务体,这是gulp.js的核心,比如下面是非常简单的任务函数:
gulp.task(“test”,function(){console.log(“111”)});
task方法还可以指定按顺序运行的一组任务,如下:
gulp.task(“build”,[‘css’,’js’,’java’]);
上面的代码先指定build任务,它按次序有css,js,java三个任务组成,注意:每个任务都是异步调用,所以没有办法保证是那个任务先执行完。
如果希望要按照严格的顺序执行完,可以如下写代码:
gulp.task(‘css’,[‘js’],function(){});
如上代码表明:css的任务依赖于js,所以css一定会在js运行完成后在执行。
如果一个任务名字为default,它表示默认任务,在命令行中直接运行gulp即可。
gulp.task(‘default’,function(){});
2.gulp.src(globs[,options]):指明源文件的路径,options是可选的。
有以下几种形式:
1.js/app.js 指明确切的文件名。
2.js/*.js 某个目录所有后缀名为js的文件。
3.js/**/*.js 某个目录及其所有子目录中的所有后缀名为js的文件。
4.!js/app.js 除了js/app.js以外的所有文件
5. *.+(js|css) 匹配项目的根目录下,所有后缀名为js或css的文件。
Src方法的参数还可以是一个数组,用来指定多个成员,如下:
gulp.src([‘js/**/*.js’,!js/app.js]).
3. gulp.dest(path) 指明任务处理后的目标输出路径。
4.gulp.watch(globs[,options],task)/gulp.watch(globs[,options,cb]),监听文件的变化并运行相应的任务。
如上gulpfile.js代码,我监听了jshint及minify代码,只要语法错误就会在命令行给出提示:如下所示:
官网有更多的关于gulp插件(http://gratimax.net/search-gulp-plugins/) 我们可以根据自己的需求,来需要某个模块,注册任务和执行还是上面一样的。
npm install gulp-htmlmin gulp-imagemin imagemin-pngcrush gulp-minify-css gulp-jshint gulp-uglify gulp-concat gulp-rename gulp-notify --save-dev
gulp配置文件如下:
//在你的项目根目录下创建gulpfile.js,代码如下: // 引入 gulp var gulp = require(\'gulp\'); // 引入组件 var htmlmin = require(\'gulp-htmlmin\'), //html压缩 imagemin = require(\'gulp-imagemin\'),//图片压缩 pngcrush = require(\'imagemin-pngcrush\'), minifycss = require(\'gulp-minify-css\'),//css压缩 jshint = require(\'gulp-jshint\'),//js检测 uglify = require(\'gulp-uglify\'),//js压缩 concat = require(\'gulp-concat\'),//文件合并 rename = require(\'gulp-rename\'),//文件更名 notify = require(\'gulp-notify\');//提示信息 // 压缩html gulp.task(\'html\', function() { return gulp.src(\'src/*.html\') .pipe(htmlmin({collapseWhitespace: true})) .pipe(gulp.dest(\'./dest\')) .pipe(notify({ message: \'html task ok\' })); }); // 压缩图片 gulp.task(\'img\', function() { return gulp.src(\'src/images/*\') .pipe(imagemin({ progressive: true, svgoPlugins: [{removeViewBox: false}], use: [pngcrush()] })) .pipe(gulp.dest(\'./dest/images/\')) .pipe(notify({ message: \'img task ok\' })); }); // 合并、压缩、重命名css gulp.task(\'css\', function() { return gulp.src(\'src/css/*.css\') .pipe(concat(\'main.css\')) .pipe(gulp.dest(\'dest/css\')) .pipe(rename({ suffix: \'.min\' })) .pipe(minifycss()) .pipe(gulp.dest(\'dest/css\')) .pipe(notify({ message: \'css task ok\' })); }); // 检查js gulp.task(\'lint\', function() { return gulp.src(\'src/js/*.js\') .pipe(jshint()) .pipe(jshint.reporter(\'default\')) .pipe(notify({ message: \'lint task ok\' })); }); // 合并、压缩js文件 gulp.task(\'js\', function() { return gulp.src(\'src/js/*.js\') .pipe(concat(\'all.js\')) .pipe(gulp.dest(\'dest/js\')) .pipe(rename({ suffix: \'.min\' })) .pipe(uglify()) .pipe(gulp.dest(\'dest/js\')) .pipe(notify({ message: \'js task ok\' })); }); // 默认任务 gulp.task(\'default\', function(){ gulp.run(\'img\', \'css\', \'lint\', \'js\', \'html\'); // 监听html文件变化 gulp.watch(\'src/*.html\', function(){ gulp.run(\'html\'); }); // Watch .css files gulp.watch(\'src/css/*.css\', [\'css\']); // Watch .js files gulp.watch(\'src/js/*.js\', [\'lint\', \'js\']); // Watch image files gulp.watch(\'src/images/*\', [\'img\']); });
Gulp 学习总结
Gulp 自动化工具开发非常方便,便于上手,值得使用。
一、Gulp安装
gulp是基于NodeJS运行的,所以需要想安装NodeJS. http://nodejs.org/download/
安装gulp
# 安装全局环境 npm install gulp -g #安装本地环境 npm install gulp --save-dev
二、Gulp插件安装
npm install browser-sync gulp-compass gulp-sass gulp-rename gulp-jshint gulp-uglify gulp-concat gulp-imagemin gulp-cache gulp-connect gulp-minify-css gulp-sourcemaps gulp-notify gulp-livereload gulp-clean gulp-load-plugins gulp-rev-append gulp-make-css-url-version --save-dev
插件可根据自己的需求安装,分别代表:
1、编译Sass,生成雪碧图(gulp-compass);
2、编译sass(gulp-sass);
3、sass浏览器地图(gulp-sourcemaps);
4、重命名文件(gulp-rename);
5、JS语法检测(gulp-jshint);
6、JS丑化(gulp-uglify);
7、JS文件合并(gulp-concat);
8、图片压缩(gulp-imagemin);
9、缓存通知(gulp-cache);
10、web服务(gulp-connect);
11、压缩CSS(gulp-minify-css);
12、css文件引用URL图片加版本号(gulp-make-css-url-version);
13、清空文件夹(gulp-clean);
14、更新通知(gulp-notify);
15、html文件引用加版本号(gulp-rev-append);
16、web服务浏览器同步浏览(browser-sync); // 推荐使用这个作为web服务
三、创建配置文件gulpfile.js
1、引入插件
var gulp = require(\'gulp\'), compass = require(\'gulp-compass\'), // compass编译Sass, 生成雪碧图 sass = require(\'gulp-sass\'), // sass编译 sourcemaps = require(\'gulp-sourcemaps\'), // sass地图 rename = require(\'gulp-rename\'), // 重命名文件 jshint = require(\'gulp-jshint\'), // JS语法检测 uglify = require(\'gulp-uglify\'), // JS丑化 concat = require(\'gulp-concat\'), // JS拼接 imagemin = require(\'gulp-imagemin\'), // 图片压缩 cache = require(\'gulp-cache\'), // 缓存通知 connect = require(\'gulp-connect\'), // web服务 minifycss = require(\'gulp-minify-css\'), // 压缩CSS cssver = require(\'gulp-make-css-url-version\'), // css文件引用URL加版本号 clean = require(\'gulp-clean\'), // 清空文件夹 notify = require(\'gulp-notify\'), // 更新通知 rev = require(\'gulp-rev-append\'), // html添加版本号 browserSync = require(\'browser-sync\'), // 浏览器同步 reload = browserSync.reload; // 自动刷新
2、配置开发路径,结构为:
/*****项目结构***** * project(项目名称) * |–node_modules 组件目录 * |–dist 发布环境 * |–css 样式文件(压缩) * |–images 图片文件(压缩图片) * |–js js文件(压缩) * |–index.html 静态文件(压缩html) * |–dev 生产环境 * |–sass sass文件 * |–images 图片文件 * |–js js文件 * |–index.html 静态文件 * |–config.rb Compass配置文件 * |–package.json 项目信息 * |–gulpfile.js gulp任务文件 **/
gulpfile.js配置文件中的路径为:
// 路径变量 var path = { // 开发环境 dev: { html: \'./dev\', js: \'./dev/js\', sass: \'./dev/sass\', css: \'./dev/css\', image: \'./dev/images\' }, // 发布环境 dist: { html: \'./dist\', js: \'./dist/js\', css: \'./dist/css\', image: \'./dist/images\' } };
3、构建gulp执行任务
// 定义web服务模块,增加浏览器同步浏览 gulp.task(\'browser-sync\', function() { browserSync({ server: { baseDir: \'.\' } }); }); // 创建Compass任务,编译Sass生成雪碧图 gulp.task(\'compass\', function() { gulp.src(path.dev.sass+\'/*.scss\') .pipe(compass({ config_file: \'./config.rb\', // 配置文件 css: path.dev.css, // 编译路径 sass: path.dev.sass // sass路径 //image: path.dev.image // 图片路径,用于生成雪碧图 })) .pipe(cssver()) // CSS文件引用URl加版本号 .pipe(minifycss()) // 压缩CSS .pipe(gulp.dest(path.dist.css)) // 发布到线上版本 .pipe(reload({stream: true})); }); // 压缩HTML gulp.task(\'html\', function() { gulp.src(path.dev.html+"/*.html") .pipe(rev()) // html 引用文件添加版本号 .pipe(gulp.dest(path.dist.html)) .pipe(reload({stream: true})); }); //检查脚本 gulp.task(\'lint\', function() { gulp.src(path.dev.js+\'/*.js\') .pipe(jshint()) .pipe(jshint.reporter(\'default\')); });// 图片压缩 gulp.task(\'image\', function() { gulp.src(path.dev.image+\'/*.*\') .pipe(cache(imagemin())) .pipe(reload({stream: true})) .pipe(gulp.dest(path.dist.image)); //.pipe(notify({ message: \'图片压缩\'})); }); // 合并压缩JS文件 gulp.task(\'script\', function() { gulp.src(path.dev.js+\'/*.js\') //.pipe(concat(\'all.js\')) // 合并 //.pipe(gulp.dest(path.dist.js)) //.pipe(rename(\'all.min.js\')) // 重命名 .pipe(uglify()) // 压缩 .pipe(gulp.dest(path.dist.js)) //.pipe(notify({ message: \'JS合并压缩\' })) .pipe(reload({stream: true})); }); // 清空文件夹 gulp.task(\'clean\', function() { gulp.src([path.dist.css, path.dist.js, path.dist.image], {read: false}) .pipe(clean()); }); // 默认任务 gulp.task("default", function() { gulp.run(\'browser-sync\', \'lint\', \'compass\', \'script\', \'image\'); // 检测文件发送变化 - 分开监听为了执行对应的命令 gulp.watch(path.dev.html+\'/*.*\', [\'html\']); gulp.watch(path.dev.sass+\'/*.scss\', [\'compass\']); gulp.watch(path.dev.image+\'/**\', [\'image\']); gulp.watch(path.dev.js+\'/*.js\', [\'lint\', \'script\']); });
注意:html文件引用增加版本号时,需要在html文件引用路径中增加 ?rev=@@hash 方可在编译时,自动添加版本号
<link rel="stylesheet" type="text/css" href="./css/main.css?rev=@@hash">
4、配置浏览器自动刷新问题
使用gulp的browser-sync插件可以实现浏览器自动刷新,同步浏览的功能,创建实现自动刷新,需要启动自动刷新的插件,在引入插件处
var browserSync = require(\'browser-sync\'), // 浏览器同步 reload = browserSync.reload; // 自动刷新
之后,创建browser-sync的task任务,并在gulp的启用。
gulp.task(\'browser-sync\', function() { browserSync({ server: { baseDir: \'.\' } }); });
baseDir 为默认的服务访问路径,默认访问为 http://localhost:3000, 配置信息为 http://localhost:3001
然后在发生变化要刷新的任务处,添加如下语句即可。详情参考: BrowserSync + Gulp.js
.pipe(reload({stream: true}));
gulpfile.js完整文件如下:
/** * *****组件安装***** * npm install gulp browser-sync gulp-compass gulp-sass gulp-rename gulp-jshint gulp-uglify gulp-concat gulp-imagemin gulp-cache gulp-connect gulp-minify-css gulp-sourcemaps gulp-notify gulp-livereload gulp-clean gulp-load-plugins gulp-rev-append gulp-make-css-url-version --save-dev * * *****项目结构***** * project(项目名称) * |–.svn 通过svn管理项目会生成这个文件夹 * |–node_modules 组件目录 * |–dist 发布环境 * |–css 样式文件(style.css style.min.css) * |–images 图片文件(压缩图片) * |–js js文件(main.js main.min.js) * |–index.html 静态文件(压缩html) * |–dev 生产环境 * |–sass sass文件 * |–images 图片文件 * |–js js文件 * |–index.html 静态文件 * |–config.rb Compass配置文件
* |-package.json 项目信息 * |–gulpfile.js gulp任务文件 **/ // 引入 Gulp插件 var gulp = require(\'gulp\'), compass = require(\'gulp-compass\'), // compass编译Sass, 生成雪碧图 sass = require(\'gulp-sass\'), // sass编译 sourcemaps = require(\'gulp-sourcemaps\'), // sass地图 rename = require(\'gulp-rename\'), // 重命名文件 jshint = require(\'gulp-jshint\'), // JS语法检测 uglify = require(\'gulp-uglify\'), // JS丑化 concat = require(\'gulp-concat\'), // JS拼接 imagemin = require(\'gulp-imagemin\'), // 图片压缩 cache = require(\'gulp-cache\'), // 缓存通知 connect = require(\'gulp-connect\'), // web服务 minifycss = require(\'gulp-minify-css\'), // 压缩CSS cssver = require(\'gulp-make-css-url-version\'), // css文件引用URL加版本号 clean = require(\'gulp-clean\'), // 清空文件夹 notify = require(\'gulp-notify\'), // 更新通知 rev = require(\'gulp-rev-append\'), // html添加版本号 browserSync = require(\'browser-sync\'), // 浏览器同步 reload = browserSync.reload; // 自动刷新 // 路径变量 var path = { // 开发环境 dev: { html: \'./dev\', js: \'./dev/js\', sass: \'./dev/sass\', css: \'./dev/css\', image: \'./dev/images\' }, // 发布环境 dist: { html: \'./dist\', js: \'./dist/js\', css: \'./dist/css\', image: \'./dist/images\' } }; // 定义web服务模块 gulp.task(\'webserver\', function() { connect.server({ livereload: true, port: 8888 }); }); // 定义web服务模块,增加浏览器同步浏览 gulp.task(\'browser-sync\', function() { browserSync({ server: { baseDir: \'.\' } }); }); // 创建Compass任务,编译Sass生成雪碧图 gulp.task(\'compass\', function() { gulp.src(path.dev.sass+\'/*.scss\') .pipe(compass({ config_file: \'./config.rb\', // 配置文件 css: path.dev.css, // 编译路径 sass: path.dev.sass // sass路径 //image: path.dev.image // 图片路径,用于生成雪碧图 })) .pipe(cssver()) // CSS文件引用URl加版本号 .pipe(minifycss()) // 压缩CSS .pipe(gulp.dest(path.dist.css)) // 发布到线上版本 .pipe(reload({stream: true})); }); // 压缩HTML gulp.task(\'html\', function() { gulp.src(path.dev.html+"/*.html") .pipe(rev()) // html 引用文件添加版本号 .pipe(gulp.dest(path.dist.html)) .pipe(reload({stream: true})); }); //检查脚本 gulp.task(\'lint\', function() { gulp.src(path.dev.js+\'/*.js\') .pipe(jshint()) .pipe(jshint.reporter(\'default\')); }); // 图片压缩 gulp.task(\'image\', function() { gulp.src(path.dev.image+\'/*.*\') .pipe(cache(imagemin())) .pipe(reload({stream: true})) .pipe(gulp.dest(path.dist.image)); //.pipe(notify({ message: \'图片压缩\'})); }); // 合并压缩JS文件 gulp.task(\'script\', function() { gulp.src(path.dev.js+\'/*.js\') //.pipe(concat(\'all.js\')) // 合并 //.pipe(gulp.dest(path.dist.js)) //.pipe(rename(\'all.min.js\')) // 重命名 .pipe(uglify()) // 压缩 .pipe(gulp.dest(path.dist.js)) //.pipe(notify({ message: \'JS合并压缩\' })) .pipe(reload({stream: true})); }); // 清空文件夹 gulp.task(\'clean\', function() { gulp.src([path.dist.css, path.dist.js, path.dist.image], {read: false}) .pipe(clean()); }); // 默认任务 gulp.task("default", function() { gulp.run(\'browser-sync\', \'lint\', \'compass\', \'script\', \'image\'); // 检测文件发送变化 - 分开监听为了执行对应的命令 gulp.watch(path.dev.html+\'/*.*\', [\'html\']); gulp.watch(path.dev.sass+\'/*.scss\', [\'compass\']); gulp.watch(path.dev.image+\'/**\', [\'image\']); gulp.watch(path.dev.js+\'/*.js\', [\'lint\', \'script\']); });
gulp-compass 合并雪碧图使用的 config.rb 配置文件,内容如下:
# Set this to the root of your project when deployed: http_path = "/" css_dir = "./dev/css" sass_dir = "./dev/sass" images_dir = "./dev/images" javascripts_dir = "./dev/js" # You can select your preferred output style here (can be overridden via the command line): # 合并雪碧图的方式 # output_style = :expanded or :nested or :compact or :compressed # To enable relative paths to assets via compass helper functions. Uncomment: # 相对路径 relative_assets = true # To disable debugging comments that display the original location of your selectors. Uncomment: # line_comments = false # If you prefer the indented syntax, you might want to regenerate this # project again passing --syntax sass, or you can uncomment this: # preferred_syntax = :sass # and then run: # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
四、运行gulp
在项目目录下执行 gulp
命令就会运行 default
任务,并且启动监听,之所以分开设置监听任务,是为了执行对应命令,如果合并在一起执行,会增加编译时间。
五、gulpfile.js配置文件参数说明
1、gulp.task()
gulp模块的task方法,用于定义具体的任务,第一个参数为任务名,第二个参数为任务函数,如image任务,调用直接运行 gulp image
gulp.task(\'image\', function() { console.log(\'图片任务执行\'); });
task方法也可以知道一组任务,如:
gulp.task(\'default\',[\'html\', \'sass\', \'js\']);
2、gulp.src()
gulp模块的src方法,用于产生数据流,表示要处理的文件,一般有以下几种格式:
- js/app.js:指定确切的文件名。
- js/*.js:某个目录所有后缀名为js的文件。
- js/**/*.js:某个目录及其所有子目录中的所有后缀名为js的文件。
- !js/app.js:除了js/app.js以外的所有文件。
- *.+(js|css):匹配项目根目录下,所有后缀名为js或css的文件。
src方法的参数可以是一个数组,如:
gulp.src([\'./js/*.js\', \'./sass/*.scss\']);
3、gulp.watch()
gulp模块的watch方法,用于指点需要监视的文件,一旦文件发生变动,就运行指点任务。
gulp.watch(\'./js/*.js\', [\'lint\', \'script\']);
4、pipe
.pipe为每个任务的连接,执行完一个任务之后,再次连接执行下一个任务,如:
.pipe(minifycss()) // 压缩CSS .pipe(gulp.dest(path.dist.css)); // 发布到线上版本
先执行压缩,再发布到线上版本
六、gulp学习资料参考
1、Gulp.js:比 Grunt 更简单的自动化的项目构建利器
2、Gulp使用指南
8、https://www.npmjs.com/package/gulp
混淆JavaScript代码的gulp插件:gulp-obfuscate
gulp-obfuscate是一个混淆JavaScript代码的gulp插件。
Install
$ npm install --save-dev gulp-obfuscate
用法
var gulp = require(\'gulp\');var obfuscate = require(\'gulp-obfuscate\'); gulp.task(\'default\', function () { return gulp.src(\'test.js\') .pipe(obfuscate()); });
demo:
package.json
{ "name": "tongbanke", "version": "1.0.0", "description": "tobanke\'", "main": "main.js", "scripts": { "test": "test" }, "repository": { "type": "git", "url": "gulp" }, "keywords": [ "gulp", "test" ], "author": "kongzhi", "license": "ISC", "devDependencies": { "gulp": "^3.6.2", "gulp-coffee": "^1.4.2", "gulp-concat": "^2.6.0", "gulp-connect": "^2.3.1", "gulp-jshint": "^2.0.1", "gulp-less": "^3.1.0", "gulp-obfuscate": "^0.2.9", "gulp-uglify": "^2.0.0", "gulp-watch": "^0.6.2", "jshint": "^2.9.3" } }
gulpfile:
var gulp = require(\'gulp\'); var concat = require(\'gulp-concat\'); //文件合并 var uglify = require(\'gulp-uglify\'); //文件压缩 var rename = require(\'gulp-rename\'); //文件重命名 var obfuscate = require(\'gulp-obfuscate\'); //代码混淆 // 语法检查 gulp.task(\'lint\', function() { console.log(\'111\'); return gulp.src(\'src/*.js\') .pipe(jshint()) .pipe(jshint.reporter(\'default\')); }); // 合并文件之后压缩代码 gulp.task(\'minify\', function() { console.log(\'压缩合并\'); return gulp.src(\'src/*.js\') .pipe(concat(\'main.js\')) .pipe(gulp.dest(\'min.js\')) .pipe(uglify()) .pipe(rename(\'main.min.js\')) .pipe(gulp.dest(\'min.js\')); }); // 监视文件的变化 gulp.task(\'watch\', function() { console.log(\'文件有变换\'); gulp.watch(\'src/*.js\', [\'minify\']); }); // 注册缺省任务 gulp.task(\'default\', [\'minify\', \'watch\'], function() { console.log(\'IS OK!\'); return gulp.src(\'main.min.js\') .pipe(obfuscate()); //压缩完代码混淆 });
原创翻译,有不当的地方欢迎指出。转载请指明出处。谢谢!
对网站资源进行优化,并使用不同浏览器测试并不是网站设计过程中最有意思的部分,但是这个过程中的很多重复的任务能够使用正确的工具自动完成,从而使效率大大提高,这是让很多开发者觉得有趣的地方。
Gulp是一个构建系统,它能通过自动执行常见任务,比如编译预处理CSS,压缩JavaScript和刷新浏览器,来改进网站开发的过程。通过本文,我们将知道如何使用Gulp来改变开发流程,从而使开发更加快速高效。
What Is Gulp?
Gulp是一个构建系统,开发者可以使用它在网站开发过程中自动执行常见任务。Gulp是基于Node.js构建的,因此Gulp源文件和你用来定义任务的Gulp文件都被写进了JavaScript(或者CoffeeScript)里。前端开发工程师还可以用自己熟悉的语言来编写任务去lint JavaScript和CSS、解析模板以及在文件变动时编译LESS文件(当然这些只是一小部分例子)。
Gulp本身虽然不能完成很多任务,但它有大量插件可用,开发者可以访问插件页面或者在npm搜索gulpplugin就能看到。例如,有些插件可以用来执行JSHint、编译CoffeeScript,执行Mocha测试,甚至更新版本号。
对比其他构建工具,比如Grunt,以及最近流行的Broccoli,我相信Gulp会更胜一筹(请看后面的”Why Gulp?”部分),同时我汇总了一个使用Javascript编写的构建工具清单,可供大家参考。
Gulp是一个可以在GitHub上找到的开源项目。
Installing Gulp
安装Gulp的过程十分简单。首先,需要在全局安装Gulp包:
npm install -g gulp
然后,在项目里面安装Gulp:
npm install --save-dev gulp
Using Gulp
现在我们创建一个Gulp任务来压缩JavaScript文件。首先创建一个名为gulpfile.js的文件,这是定义Gulp任务的地方,它可以通过gulp命令来运行,接着把下面的代码放到gulpfile.js文件里面。
var gulp = require(\'gulp\'),
uglify = require(\'gulp-uglify\');
gulp.task(\'minify\', function () {
gulp.src(\'js/app.js\')
.pipe(uglify())
.pipe(gulp.dest(\'build\'))
});
然后在npm里面运行npm install -–save-dev gulp-uglify来安装gulp-uglify,最后通过运行gulp minify来执行任务。假设js目录下有个app.js文件,那么一个新的app.js将被创建在编译目录下,它包含了js/app.js的压缩内容。想一想,到底发生了什么?
我们只在gulpfile.js里做了一点事情。首先,我们加载gulp和gulp-uglify模块:
var gulp = require(\'gulp\'),
uglify = require(\'gulp-uglify\');
然后,我们定义了一个叫minify的任务,它执行时会调用函数,这个函数会作为第二个参数:
gulp.task(\'minify\', function () {
});
最后,也是难点所在,我们需要定义任务应该做什么:
gulp.src(\'js/app.js\')
.pipe(uglify())
.pipe(gulp.dest(\'build\'))
如果你对数据流非常熟悉(其实大多数前端开发人员并不熟悉),上面所提供的代码对你来说就没有太大意义了。
STREAMS
数据流能够通过一系列的小函数来传递数据,这些函数会对数据进行修改,然后把修改后的数据传递给下一个函数。
在上面的例子中,gulp.src()函数用字符串匹配一个文件或者文件的编号(被称为“glob”),然后创建一个对象流来代表这些文件,接着传递给uglify()函数,它接受文件对象之后返回有新压缩源文件的文件对象,最后那些输出的文件被输入gulp.dest()函数,并保存下来。
整个数据流动过程如下图所示:
当只有一个任务的时候,函数并不会起太大的作用。然而,仔细思考下面的代码:
gulp.task(\'js\', function () {
return gulp.src(\'js/*.js\')
.pipe(jshint())
.pipe(jshint.reporter(\'default\'))
.pipe(uglify())
.pipe(concat(\'app.js\'))
.pipe(gulp.dest(\'build\'));
});
在运行这段程序之前,你需要先安装gulp,gulp-jshint,gulp-uglify和gulp-concat。
这个任务会让所有的文件匹配js/*.js(比如js目录下的所有JavaScript文件),并且执行JSHint,然后打印输出结果,取消文件缩进,最后把他们合并起来,保存为build/app.js,整个过程如下图所示:
如果你对Grunt 足够熟悉,就会注意到,Gulp和Grunt的工作方式很不一样。Grunt不使用数据流,而是使用文件,对文件执行单个任务然后保存到新的文件中,每个任务都会重复执行所有进程,文件系统频繁的处理任务会导致Grunt的运行速度比Gulp慢。
如果想要获取更加全面的数据流知识,请查看“Stream Handbook”.
GULP.SRC()
gulp.src()方法输入一个glob(比如匹配一个或多个文件的字符串)或者glob数组,然后返回一个可以传递给插件的数据流。
Gulp使用node-glob来从你指定的glob里面获取文件,这里列举下面的例子来阐述,方便大家理解:
- js/app.js 精确匹配文件
- js/*.js 仅匹配js目录下的所有后缀为.js的文件
- js/*/.js 匹配js目录及其子目录下所有后缀为.js的文件
- !js/app.js 从匹配结果中排除js/app.js,这种方法在你想要匹配除了特殊文件之外的所有文件时非常管用
- *.+(js|css) 匹配根目录下所有后缀为.js或者.css的文件
此外,Gulp也有很多其他的特征,但并不常用。如果你想了解更多的特征,请查看Minimatch文档。
js目录下包含了压缩和未压缩的JavaScript文件,现在我们想要创建一个任务来压缩还没有被压缩的文件,我们需要先匹配目录下所有的JavaScript文件,然后排除后缀为.min.js的文件:
gulp.src([\'js/**/*.js\', \'!js/**/*.min.js\'])
DEFINING TASKS
gulp.task()函数通常会被用来定义任务。当你定义一个简单的任务时,需要传入任务名字和执行函数两个属性。
gulp.task(\'greet\', function () {
console.log(\'Hello world!\');
});
执行gulp greet的结果就是在控制台上打印出“Hello world”.
一个任务有时也可以是一系列任务。假设要定义一个任务build来执行css、js、imgs这三个任务,我们可以通过指定一个任务数组而不是函数来完成。
gulp.task(\'build\', [\'css\', \'js\', \'imgs\']);
这些任务不是同时进行的,所以你不能认为在js任务开始的时候css任务已经结束了,也可能还没有结束。为了确保一个任务在另一个任务执行前已经结束,可以将函数和任务数组结合起来指定其依赖关系。例如,定义一个css任务,在执行前需要检查greet任务是否已经执行完毕,这样做就是可行的:
gulp.task(\'css\', [\'greet\'], function () {
// Deal with CSS here
});
现在,当执行css任务时,Gulp会先执行greet任务,然后在它结束后再调用你定义的函数。
DEFAULT TASKS
你可以定义一个在gulp开始运行时候默认执行的任务,并将这个任务命名为“default”:
gulp.task(\'default\', function () {
// Your default task
});
PLUGINS
Gulp上有超过600种插件供你选择,你可以在插件页面或者npm上搜索gulpplugin来浏览插件列表。有些拥有“gulpfriendly”标签的插件,他们不能算插件,但是能在Gulp上正常运行。 需要注意的是,当直接在npm里搜索时,你无法知道某一插件是否在黑名单上(你需要滚动到插件页面底部才能看到)。
大多数插件的使用都很方便,它们都配有详细的文档,而且调用方法也相同(通过传递文件对象流给它),它们通常会对这些文件进行修改(但是有一些插件例外,比如validators),最后返回新的文件给下一个插件。
让我们用前面的js任务来详细说明一下:
var gulp = require(\'gulp\'),
jshint = require(\'gulp-jshint\'),
uglify = require(\'gulp-uglify\'),
concat = require(\'gulp-concat\');
gulp.task(\'js\', function () {
return gulp.src(\'js/*.js\')
.pipe(jshint())
.pipe(jshint.reporter(\'default\'))
.pipe(uglify())
.pipe(concat(\'app.js\'))
.pipe(gulp.dest(\'build\'));
});
这里使用了三个插件,gulp-jshint,gulp-uglify和gulp-concat。开发者可以参考插件的README文档,插件有很多配置选项,而且
以上是关于Gulp 学习笔记的主要内容,如果未能解决你的问题,请参考以下文章