Gulp
是一个基于 nodejs
的流式构建工具,它通过代码优于配置的策略不仅使得任务容易写,并且更加容易阅读和维护。Gulp
使用的 NodeJS
的流,无需在硬盘上写入临时文件和目录,让任务构建更加迅速。
下面是一个 Gulp
配置示例:
gulp.task('sass', function() { return gulp.src('src/styles/main.scss') .pipe(sass({ style: 'compressed' })) .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4')) .pipe(gulp.dest('dist/assets/css')) });
上面这个例子可以看出,main.css 文件像水流一样经过Sass
和 Autoprefixer
插件的一系列处理,最终输出结果文件,一切是那么的简单,并且执行起来非常的快。
安装gulp
在深入研究任务配置前,我们先安装gulp:
$ npm install gulp -g
这个是全局安装,如果我们想安装到项目里面,请先进入到项目目录,然后运行下面命令(确保项目下面有 package.json
文件):
$ npm install gulp --save-dev
安装后,将会把 gulp 写入到 package.json
的 devDependencies
里面。
安装 gulp 插件
我们先安装下面的几个插件来实现后面的任务:
- Sass compile (gulp-ruby-sass)
- Autoprefixer (gulp-autoprefixer)
- Minify CSS (gulp-minify-css)
- JSHint (gulp-jshint)
- Concatenation (gulp-concat)
- Uglify (gulp-uglify)
- Compress images (gulp-imagemin)
- LiveReload (gulp-livereload)
- Caching of images so only changed images are compressed (gulp-cache)
- Notify of changes (gulp-notify)
- Clean files for a clean build (del)
可以使用下面的命令来安装这些插件:
$ npm install gulp-ruby-sass gulp-autoprefixer gulp-minify-css \ gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify \ gulp-rename gulp-livereload gulp-cache del --save-dev
执行后,这些插件将会写入 package.json
的 devDependencies
中。在这儿可以查找更多插件。
加载插件
接着,我们需要创建 gulpfile.js
并且加载插件:
var gulp = require('gulp'), sass = require('gulp-ruby-sass'), autoprefixer = require('gulp-autoprefixer'), minifycss = require('gulp-minify-css'), jshint = require('gulp-jshint'), uglify = require('gulp-uglify'), imagemin = require('gulp-imagemin'), rename = require('gulp-rename'), concat = require('gulp-concat'), notify = require('gulp-notify'), cache = require('gulp-cache'), livereload = require('gulp-livereload'), del = require('del');
乍一看,感觉这比 Grant 还要复杂啊,然而这正是与 Grant 的不同之处。Gulp 每个插件要做的事都只做一件事,互不影响。
创建任务
1. 编译Sass, Autoprefix 和 minify
gulp.task('styles', function() { return gulp.src('src/styles/main.scss') .pipe(sass({ style: 'expanded' })) .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4')) .pipe(gulp.dest('dist/assets/css')) .pipe(rename({suffix: '.min'})) .pipe(minifycss()) .pipe(gulp.dest('dist/assets/css')) .pipe(notify({ message: 'Styles task complete' })); });
首先我们先配置 Sass
编译。使用 expanded
方式处理Sass文件,通过 Autoprefixer
处理前缀,保存至目标路径,接着给文件增加 .min
后缀,然后使用 minifycss
压缩,最后在结束的时候发出完成通知。
其中 gulp.src
API 可以使用正则匹配多个文件,例如
/**/*.scss
返回所有的scss文件。
2. 使用 JSHint
, concat
和 minify
处理 JavaScript
我们开始处理JavaScript
gulp.task('scripts', function() { return gulp.src('src/scripts/**/*.js') .pipe(jshint('.jshintrc')) .pipe(jshint.reporter('default')) .pipe(concat('main.js')) .pipe(gulp.dest('dist/assets/js')) .pipe(rename({suffix: '.min'})) .pipe(uglify()) .pipe(gulp.dest('dist/assets/js')) .pipe(notify({ message: 'Scripts task complete' })); });
需要注意的一点是,我们需要给 JSHint
指定一个 reporter
,我一般使用默认的 reporter
,这比较适合大多数人,你可以从JSHint官网了解更多。
3. 压缩图片
接下来我们开始编写图片压缩模块:
gulp.task('images', function() { return gulp.src('src/images/**/*') .pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })) .pipe(gulp.dest('dist/assets/img')) .pipe(notify({ message: 'Images task complete' })); });
使用 imagemin
插件压缩任何类型的图片, 我们可以更进一步利用缓存来保存压缩过的图片,安装 gulp-cahce 插件就可以了,然后我们可以把下面这行做下修改:
.pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))
改为
.pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
清除目标文件
在部署之前先清除一下目标文件是个很好的习惯,代码如下:
gulp.task('clean', function(cb) { del(['dist/assets/css', 'dist/assets/js', 'dist/assets/img'], cb) });
编写默认任务
默认任务是 gulp 运行的入口,下面我们编写的默认任务将会执行以上3个任务:
gulp.task('default', ['clean'], function() { gulp.start('styles', 'scripts', 'images'); });
注意 gulp.task
中的数组,在执行 gulp.start
之前会先执行数组中的任务,在这个例子中就是先清除,然后再运行后面3个任务。
Watch 和 LiveReload
我们可以使用 Watch
来监听指定文件和 LiveReload
设置实现自动刷新。
gulp.task('watch', function() { // Watch .scss files gulp.watch('src/styles/**/*.scss', ['styles']); // Watch .js files gulp.watch('src/scripts/**/*.js', ['scripts']); // Watch image files gulp.watch('src/images/**/*', ['images']); }); gulp.task('watch', function() { // Create LiveReload server livereload.listen(); // Watch any files in dist/, reload on change gulp.watch(['dist/**']).on('change', livereload.changed); });
整合所有任务
/*! * gulp * $ npm install gulp-ruby-sass gulp-autoprefixer gulp-minify-css gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-livereload gulp-cache del --save-dev */ // Load plugins var gulp = require('gulp'), sass = require('gulp-ruby-sass'), autoprefixer = require('gulp-autoprefixer'), minifycss = require('gulp-minify-css'), jshint = require('gulp-jshint'), uglify = require('gulp-uglify'), imagemin = require('gulp-imagemin'), rename = require('gulp-rename'), concat = require('gulp-concat'), notify = require('gulp-notify'), cache = require('gulp-cache'), livereload = require('gulp-livereload'), del = require('del'); // Styles gulp.task('styles', function() { return gulp.src('src/styles/main.scss') .pipe(sass({ style: 'expanded', })) .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4')) .pipe(gulp.dest('dist/styles')) .pipe(rename({ suffix: '.min' })) .pipe(minifycss()) .pipe(gulp.dest('dist/styles')) .pipe(notify({ message: 'Styles task complete' })); }); // Scripts gulp.task('scripts', function() { return gulp.src('src/scripts/**/*.js') .pipe(jshint('.jshintrc')) .pipe(jshint.reporter('default')) .pipe(concat('main.js')) .pipe(gulp.dest('dist/scripts')) .pipe(rename({ suffix: '.min' })) .pipe(uglify()) .pipe(gulp.dest('dist/scripts')) .pipe(notify({ message: 'Scripts task complete' })); }); // Images gulp.task('images', function() { return gulp.src('src/images/**/*') .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))) .pipe(gulp.dest('dist/images')) .pipe(notify({ message: 'Images task complete' })); }); // Clean gulp.task('clean', function(cb) { del(['dist/assets/css', 'dist/assets/js', 'dist/assets/img'], cb) }); // Default task gulp.task('default', ['clean'], function() { gulp.start('styles', 'scripts', 'images'); }); // Watch gulp.task('watch', function() { // Watch .scss files gulp.watch('src/styles/**/*.scss', ['styles']); // Watch .js files gulp.watch('src/scripts/**/*.js', ['scripts']); // Watch image files gulp.watch('src/images/**/*', ['images']); // Create LiveReload server livereload.listen(); // Watch any files in dist/, reload on change gulp.watch(['dist/**']).on('change', livereload.changed); });