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:
1 var gulp = require('gulp'); //requires the core Gulp library 2 var g = require('gulp-load-plugins')(); //read the dependencies in the package.json file and inject each of them for us. 3 var browserSync = require('browser-sync'); 4 var del = require('del'); 5 var runSequence = require('run-sequence'); 6 7 //jshint block 8 //Stylish reporter for JSHint(reporter looked more beauty) 9 //use jshintConfig in package.json to specifying Linting Options 10 var stylish = require('jshint-stylish'); 11 var packageJSON = require('./package'); 12 //var jshintConfig = packageJSON.jshintConfig; 13 14 var paths = { 15 dist: { 16 all: 'dist/**/*', 17 js: 'dist/js', 18 css: 'dist/css', 19 img: 'dist/img', 20 html: 'dist/html', 21 lib: 'dist/lib' 22 }, 23 app: { 24 all: 'app/**/*', 25 less: 'app/style/**/*.less', 26 js: 'app/js/**/*.js', 27 img: 'app/img/**/*', 28 html: 'app/views/**/*.html' 29 } 30 }; 31 32 // Clean dist 33 gulp.task('clean', function () { 34 return del('dist/*'); 35 }); 36 37 //minifies js 38 gulp.task('minifyJS', function () { 39 return gulp.src(paths.app.js) 40 .pipe(g.uglify()) 41 .pipe(gulp.dest(paths.dist.js)); 42 }); 43 44 // Inspect js 45 gulp.task('jshint', function() { 46 gulp.src(paths.app.js) 47 .pipe(g.jshint(packageJSON.jshintConfig)) 48 .pipe(g.jshint.reporter(stylish)) 49 }); 50 51 //compress less & minify css 52 gulp.task('less', function () { 53 return gulp.src(paths.app.less) 54 .pipe(g.less()) 55 .pipe(g.minifyCss()) 56 .pipe(gulp.dest(paths.dist.css)); 57 }); 58 59 //minify HTML 60 gulp.task('minifyHTML', function () { 61 return gulp.src(paths.app.html) 62 .pipe(g.htmlmin({ 63 collapseWhitespace: true 64 })) 65 .pipe(gulp.dest(paths.dist.html)); 66 }); 67 68 // Watching static resources 69 gulp.task('watch', function () { 70 gulp.watch(paths.app.html, ['minifyHTML']); 71 gulp.watch(paths.app.less, ['less']); 72 gulp.watch(paths.app.js, ['jshint','minifyJS']); 73 }); 74 75 // Synchronously update browser 76 gulp.task('browser', function () { 77 browserSync({ 78 //proxy: 'localhost:3000', 79 //port: 3001, 80 server: './', 81 startPath: 'dist/html/index.html' 82 }); 83 84 gulp.watch([paths.app.all], browserSync.reload); 85 }); 86 87 // Only build 88 gulp.task('build', function () { 89 runSequence('clean', ['jshint','minifyJS', 'less', 'minifyHTML']); 90 }); 91 92 // Build & Watch 93 gulp.task('build-watch', ['build', 'watch'], function () { 94 console.log('App frontend is built and watching on static resources...'); 95 }); 96 97 gulp.task('default', function () { 98 //Run a series of dependent gulp tasks in order 99 runSequence('build-watch','browser'); 100 });
二、要养成看官网的习惯!!!
三、参考资料:
1、jshint官网 http://jshint.com/docs/cli/
2、jshint github链接 https://github.com/spalger/gulp-jshint
四、感谢CX大神的指导,感谢老大cyn的信任。
五、写的不好的地方请见谅。