使用 gulp 构建工程

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 文件像水流一样经过SassAutoprefixer 插件的一系列处理,最终输出结果文件,一切是那么的简单,并且执行起来非常的快。

安装gulp

在深入研究任务配置前,我们先安装gulp:

$ npm install gulp -g

这个是全局安装,如果我们想安装到项目里面,请先进入到项目目录,然后运行下面命令(确保项目下面有 package.json 文件):

$ npm install gulp --save-dev

安装后,将会把 gulp 写入到 package.json 的 devDependencies 里面。

安装 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

执行后,这些插件将会写入 package.jsondevDependencies 中。在这儿可以查找更多插件。

加载插件

接着,我们需要创建 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, concatminify 处理 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);
});

发表评论