node入门(三)——gulp运用实例
在上一篇《node入门(二)——gulpfile.js初探》中,我们知道了(看懂入门二及其参考资料)怎么运用gulp来更高效的开发,现在来示范一下。
在package.json里面配置好devDependencies:
"devDependencies": {
"browser-sync": "^2.10.1",
"del": "^2.2.0",
"gulp": "^3.9.0",
"gulp-eslint": "^1.1.1",
"gulp-if": "^2.0.0",
"gulp-less": "^3.0.5",
"gulp-load-plugins": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4",
"gulp-size": "^2.0.0",
"gulp-sourcemaps": "^1.6.0",
"gulp-uglify": "^1.5.1",
"run-sequence": "^1.1.5",
"gulp-minify-css": "^1.2.4",
"gulp-htmlmin": "^1.3.0",
"gulp-jshint": "^1.5.0",
"jshint-stylish": "^2.1.0"
}
现在开始写我们的task。
首先建立如下目录结构:

在study目录下,app是我们写代码的目录,dist是生产目录,app里写的代码在经过gulp处理之后,输出到dist下面,发版就用dist目录。
目录结构建好之后,在相应的目录下面继续建立项目目录,为了接下来的方便,在gulpfile里将目录结构写成json格式:
var paths = {
dist: {
all: 'dist/**/*',
js: 'dist/js',
css: 'dist/css',
img: 'dist/img',
html: 'dist/html',
lib: 'dist/lib'
},
app: {
all: 'app/**/*',
less: 'app/style/**/*.less',
js: 'app/js/**/*.js',
img: 'app/img/**/*',
html: 'app/views/**/*.html'
}
};
现在开始写task。
首先我们想到要编译并压缩less文件,于是写下这个task:
//compress less & minify css
gulp.task('less', function () {
return gulp.src(paths.app.less)
.pipe(g.less())
.pipe(g.minifyCss())
.pipe(gulp.dest(paths.dist.css));
});
找到所有的less文件,编译成css之后压缩,再输出到dist/css目录下。
然后我们想到可以再压缩一下html:
//minify HTML
gulp.task('minifyHTML', function () {
return gulp.src(paths.app.html)
.pipe(g.htmlmin({
collapseWhitespace: true
}))
.pipe(gulp.dest(paths.dist.html));
});
还有关于js方面,除了压缩,我们可以检查一下js的语法错误,于是分别写下两个task:
//minifies js
gulp.task('minifyJS', function () {
return gulp.src(paths.app.js)
.pipe(g.uglify())
.pipe(gulp.dest(paths.dist.js));
}); // Inspect js
gulp.task('jshint', function() {
gulp.src(paths.app.js)
.pipe(g.jshint(packageJSON.jshintConfig))
.pipe(g.jshint.reporter(stylish))
});
这里压缩js很好理解,关于检查js语法错误我补充几点:
1、pipe(g.jshint(packageJSON.jshintConfig))这里我是用了自定义语法规则,如果不自定义的话,可以直接这样使用:pipe(g.jshint())
2、自定义语法规则有四种方法,我采用的是在package.json里增加配置项jshintConfig,类似这样:
"jshintConfig": {
"asi": false,
"unused": true
}
具体配置参数去官网查询。
3、pipe(g.jshint.reporter(stylish))是把错误提示输出美化了一下,但是要多加一个叫做jshint-stylish的插件,要求不高的话默认输出就行:pipe(g.jshint.reporter("default"))
这些任务都可以独立执行,比如检查一下js有没有语法错误:
gulp jshint
但这样还不够高效,我们想在编辑器里面保存后浏览器就能立刻自动刷新,所见即所得。所以我们可以监控文件是否有改动,有就刷新浏览器。
首先写监控任务,指明要监控哪些文件,监控到改动又要做什么:
// Watching static resources
gulp.task('watch', function () {
gulp.watch(paths.app.html, ['minifyHTML']);
gulp.watch(paths.app.less, ['less']);
gulp.watch(paths.app.js, ['jshint','minifyJS']);
});
这里监控了所有的html,有改动就执行minifyHTML任务;监控所有的less,有改动就执行less任务;监控所有的js,有改动就异步执行jshint和minifyJS任务,注意这里的2个任务是异步执行的,在任务执行顺序没有特别要求的时候我们可以这么做。
现在我们监控了改动并做了相应的处理,但是浏览器还不知道这些事情已经发生了,所以我们开个服务器,当这些事情发生时好让服务器通知浏览器一声,好自动刷新,咱们就解脱了是吧。
// Synchronously update browser
gulp.task('browser', function () {
browserSync({
server: './',
startPath: 'dist/html/index.html'
});
gulp.watch([paths.app.all], browserSync.reload);
});
这里用到的是browser-sync插件,更多参数配置自行查询官网。
最后不要漏了一个重要任务——及时清理:
// Clean dist
gulp.task('clean', function () {
return del('dist/*');
});
当更新数据到dist时,先将之前的数据清理掉。
现在貌似所有的需求都达到了(实际需求当然更多,比如图片处理、打标签、打包等等),那么我们可以对任务进行组合,来提供更如任务入口。
比如,我们可以组合一个任务,一次性帮我们把js语法检查压缩(一般运行时不检测,检测作为单独的任务),less编译压缩,html压缩都给做了:
// Only build
gulp.task('build', function () {
runSequence('clean', ['jshint','minifyJS', 'less', 'minifyHTML']);
});
这里我们用到run-sequence插件,让任务按顺序执行。
我们还可以把build任务和监控任务组合起来,也就是监控到变化就build:
// Build & Watch
gulp.task('build-watch', ['build', 'watch'], function () {
console.log('App frontend is built and watching on static resources...');
});
这里我们发现task里多了个参数['build', 'watch'],意思是在执行build-watch任务之前,要先执行build和watch任务,build-watch任务对build和watch有依赖关系。
那么我们的的默认任务(运行命令gulp时执行的任务)就可以简单的这样写:
gulp.task('default', function () {
//Run a series of dependent gulp tasks in order
runSequence('build-watch','browser');
});
补充一点,gulp-load-plugins 是用来自动require gulp模块的,所有模块都要用require引入,这是commonJS规范。
附录:
一、完整的gulpfile.js:
var gulp = require('gulp'); //requires the core Gulp library
var g = require('gulp-load-plugins')(); //read the dependencies in the package.json file and inject each of them for us.
var browserSync = require('browser-sync');
var del = require('del');
var runSequence = require('run-sequence');
//jshint block
//Stylish reporter for JSHint(reporter looked more beauty)
//use jshintConfig in package.json to specifying Linting Options
var stylish = require('jshint-stylish');
var packageJSON = require('./package');
//var jshintConfig = packageJSON.jshintConfig;
var paths = {
dist: {
all: 'dist/**/*',
js: 'dist/js',
css: 'dist/css',
img: 'dist/img',
html: 'dist/html',
lib: 'dist/lib'
},
app: {
all: 'app/**/*',
less: 'app/style/**/*.less',
js: 'app/js/**/*.js',
img: 'app/img/**/*',
html: 'app/views/**/*.html'
}
};
// Clean dist
gulp.task('clean', function () {
return del('dist/*');
});
//minifies js
gulp.task('minifyJS', function () {
return gulp.src(paths.app.js)
.pipe(g.uglify())
.pipe(gulp.dest(paths.dist.js));
});
// Inspect js
gulp.task('jshint', function() {
gulp.src(paths.app.js)
.pipe(g.jshint(packageJSON.jshintConfig))
.pipe(g.jshint.reporter(stylish))
});
//compress less & minify css
gulp.task('less', function () {
return gulp.src(paths.app.less)
.pipe(g.less())
.pipe(g.minifyCss())
.pipe(gulp.dest(paths.dist.css));
});
//minify HTML
gulp.task('minifyHTML', function () {
return gulp.src(paths.app.html)
.pipe(g.htmlmin({
collapseWhitespace: true
}))
.pipe(gulp.dest(paths.dist.html));
});
// Watching static resources
gulp.task('watch', function () {
gulp.watch(paths.app.html, ['minifyHTML']);
gulp.watch(paths.app.less, ['less']);
gulp.watch(paths.app.js, ['jshint','minifyJS']);
});
// Synchronously update browser
gulp.task('browser', function () {
browserSync({
//proxy: 'localhost:3000',
//port: 3001,
server: './',
startPath: 'dist/html/index.html'
});
gulp.watch([paths.app.all], browserSync.reload);
});
// Only build
gulp.task('build', function () {
runSequence('clean', ['jshint','minifyJS', 'less', 'minifyHTML']);
});
// Build & Watch
gulp.task('build-watch', ['build', 'watch'], function () {
console.log('App frontend is built and watching on static resources...');
});
gulp.task('default', function () {
//Run a series of dependent gulp tasks in order
runSequence('build-watch','browser');
});
二、要养成看官网的习惯!!!

三、参考资料:
1、jshint官网 http://jshint.com/docs/cli/
2、jshint github链接 https://github.com/spalger/gulp-jshint
四、感谢CX大神的指导,感谢老大cyn的信任。
五、写的不好的地方请见谅。
node入门(三)——gulp运用实例的更多相关文章
- Node入门(转)
原文链接:http://www.nodebeginner.org/index-zh-cn.html Node入门 作者: Manuel Kiessling翻译: goddyzhao & Gra ...
- node入门(二)——gulpfile.js初探
本文关于gulpfile.js怎么写,利于完成个性化需求.本文开发环境默认已安装node,详情参考<node入门(一)——安装>. 一.安装gulp npm install -g gulp ...
- 【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo.服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了.同 ...
- Swift语法基础入门三(函数, 闭包)
Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: ...
- Node入门教程(1)目录
aicoder.com 全栈实习之简明 Node 入门文档 aicoder.com 线下实习: 不 8000 就业,不还实习费. 如果需要转载本文档,请联系老马,Q: 515154084 JS基础教程 ...
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...
- 3.Python爬虫入门三之Urllib和Urllib2库的基本使用
1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...
- 《Node入门》读书笔记——用Node.js开发一个小应用
Android APP的开发告一段落,一个稳定的.实现了基本功能的APP已经交付用户使用了!我和老板交流了下,接下来准备转战Node.js了,而且一部分前端的功能也要做进去!哈哈哈~~~接下来要朝一个 ...
- C#基础入门 三
C#基础入门 三 类 类使用class关键字进行声明,前面加一个访问修饰符,public class car{} 访问修饰符:修师傅可以用来修饰类和类成员等,控制它们的可见度 修饰符关键字分别为:pu ...
随机推荐
- 用Delphi7 调用.NET 2.0的WebService 所要注意的问题(Document格式和UTF8编码)
Delphi7 调用VS.NET 2005开发的基于.NET 2.0的WebService时发生了错误.查阅资料 http://www.community.borland.com/article/bo ...
- 使用cocoaPods加载框架的具体步骤:
注意事项: 1.使用之前备份一下代码.因为pod更新很快,如果某个文件名有中文,pod install 一下.整个项目可能就要废掉了. 2.如果不把pod文件推动到远程服务器. 每一次用的时候在本地p ...
- Ubuntu上命令行下卸载软件
sudo apt-get --purge remove 软件名 (加了--purge表示会删除配置) sudo apt-get autoremove (这个命令后面文章有解释) dpkg -l (查看 ...
- NSArray是强引用容器
经常比较疑惑NSArray.NSDictionary.NSSet这几个对象容器管理对象所采用的方式是“强引用”还是“弱引用”. 通过简单的命令行程序得到的结论是“NSArray.NSDictionar ...
- 「UVA524」 Prime Ring Problem 质数环
Description 输入正整数n,把整数1,2,-,n组成一个环,使得相邻两个整数之和均为素数.输出时,从整数1开始逆时针排列.同一个环恰好输出一次.n<=16. A ring is com ...
- 搜索好题UVA1601
题目 分析:如果以当前3个小写字母的位置为状态,则问题转化为图上的最短路问题.但是如果每次都判断小写字母的下一步是否合法,那就是说每次移动都需要判断5^3,肯定会超时.可以把所有可以移动的格子找出来建 ...
- noip数学
一.取模运算 (1)定义 给定一个正整数p和一个整数n 一定存在此等式 n=k*p+r;其中k,r是整数,r大于等于0小于p 称k是n除以p的商,r为n除以p的余数 说明:同余式 正整数a,b对p取模 ...
- 收藏产品判断、html 在 UIwebView里面显示
收藏产品功能 要求:用户点击收藏,如果已经收藏,用户点击就取消收藏 写法一: 点击事件{ if (!isSelect) { [sender setImage:[UIImage imageNamed: ...
- 1. jsp中<base target='' />标签用法
用于页面跳转后,页面最后跳转到哪个iframe.例子如下: index.jsp :首页 <head> <base href="<%=basePath %>&qu ...
- qq截图原理
屏幕截图实现的大体思想是:发起截图时,将当前窗口的图像保存到内存中,然后弹出一个置顶的全屏窗口,将保存的桌面图片绘制到这个全屏窗口上:初始时绘制的是灰化的桌面图像,选择截图区域后,则将选中的区域绘制成 ...