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 ...
随机推荐
- Ghost wenjian目录
SOAMANAGER打不开网页,需要配置ghost 文件, C:\Windows\System32\drivers\etc
- hihoCoder 1586 Minimum 【线段树】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1586 : Minimum 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 You are given a list of integers a0, a1, …, a2 ...
- mysql优化---in型子查询,exists子查询,from 型子查询
in型子查询引出的陷阱:(扫更少的行,不要临时表,不要文件排序就快) 题: 在ecshop商城表中,查询6号栏目的商品, (注,6号是一个大栏目) 最直观的: mysql); 误区: 给我们的感觉是, ...
- YTU 2866: 结构体---点坐标结构体
2866: 结构体---点坐标结构体 时间限制: 1 Sec 内存限制: 128 MB 提交: 499 解决: 344 题目描述 定义一个表示点坐标的结构体,输入两个点的坐标,输出这两个点中点的坐 ...
- YTU 2456: 评委打分
2456: 评委打分 时间限制: 1 Sec 内存限制: 128 MB 提交: 283 解决: 52 题目描述 一个歌唱比赛,比赛每次会从观众中随即抽取几名观众给分(观众至少有5个,分数为0~1 ...
- Intel® Media SDK(一)
A cross-platform API for developing media applications on Windows* Fast video playback, encode, proc ...
- Windows Mysql启动出现1069错误 “由于登录失败而无法启动服务” 的处理方法
问题现象 windows下mysql服务无法启动,报1069错误. 问题原因 如果Mysql启动用户的密码或者权限错误,会导致Windows服务器Mysql启动时出现"由于登录失败而无法启动 ...
- NSArray使用须知
多用firstObject方法 在iOS7之前,我们获取NSArray的第一个元素,通常使用array[0],在iOS7中,新引入了公开的firstObject方法,对于空数组,该方法返回nil,而使 ...
- 【hdu 4374】One Hundred Layer
[题目链接] 点击打开链接 [算法] 不难看出,这题可以用动态规划来解决 f[i][j]表示第i行第j列能够取得的最大分数 则如果向右走,状态转移方程为f[i][j]=max{f[i-1][k]+a[ ...
- darwin Stream Server源码分析
摘要 所谓的流式媒体简单的讲就是指人们通过网络实时的收看多媒体信息:如音频流.视频流等.与流式媒体对应的传统工作方式是下载+播放模式,即用户首先下载多媒体文件,然后再在本地播放,这种方法的一个主要缺 ...