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 ...
随机推荐
- MM02函数
ATA: ls_headdata LIKE bapimathead, ls_clientdata LIKE bapi_mara, ls_clientdatax LIKE bapi_marax, ls_ ...
- aapt2 错误
android.enableAapt2=false Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conf ...
- NEU 1683: H-Index
题目描述 Given an array of citations (each citation is a non-negative integer) of a researcher, write a ...
- bzoj4105: [Thu Summer Camp 2015]平方运算
填坑 我不知道怎么算的,但是所有环的LCM数不会超过60 然后用线段树维护这个东西,每个节点记录子树内的循环节 没到循环节的暴力枚举 复杂度是nlogn再乘以循环节长度 #include<cst ...
- SDUT OJ 2054 双向链表的实现 (结构体node指针+遍历 *【模板】)
双向链表 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 学会了单向链表,我们又多了一种解决问题的能力,单链表利用一个指针就能在内 ...
- 计算机学院大学生程序设计竞赛(2015’12)Pick Game
Pick Game Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- html5--6-68 实战前的准备工作:了解HTML5大纲算法
html5--6-68 实战前的准备工作:了解HTML5大纲算法 学习要点 了解HTML5大纲算法 在html5中有一个很重要的概念,叫做HTML5大纲算法(HTML5 Outliner),它的用途为 ...
- Android Studio自动生成带系统签名的apk
介绍签名的两种方式: 1.signapk.jar命令行方式: 如果你需要开发一个带有系统权限的app,往往需要配置SharedUserId,比如: </pre><pre name=& ...
- 【转】nose-parameterized是Python单元测试框架实现参数化的扩展
原文地址: http://www.cnblogs.com/fnng/p/6580636.html 相对而言,Python下面单元测试框架要弱上少,尤其是Python自带的unittest测试框架,不支 ...
- vs 2015 community Blend和devenv启动的区别
使用Blend启动会有部分功能无法显示 如:SVN管理插件,工具栏 使用devenv启动会全部显示