6

Gulp介绍

Gulp是一个前端开发的自动化构建工具。
前端开发往往需要把LESS/SCSS文件进行编译成CSS文件,JavaScript多文件合并成一个文件并压缩以及一些其他需要重复性操作的工作。而Gulp就是通过简单地代码配置与第三方插件的调用来帮助前端自动化完成这些操作。但不仅限于此,你还可以用Gulp完成页面在线即时预览,jshint代码检查等各种前端任务。

Gulp的一个普通任务流程如下:
图片描述

在终端里通过执行gulp task-name来执行指定任务,任务执行前可以先执行依赖任务。

本文只着重讲解Gulp的使用方法,其具体的安装及各种插件请访问Gulp官网进行查看。本教程分为两个部分:先讲解gulp的API使用及参数说明,后以一个实际项目案例作为演练。

第一节:接口说明

Gulp提供4个基础API进行调用,只需要掌握这4个API的使用方法并配合Gulp插件便能搭建一套自动化的前端开发任务系统。

  • gulp.task()

  • gulp.src()

  • gulp.dest()

  • gulp.watch()

Gulp.src(globs[, options])

此接口会匹配工作目录下指定规则的文件并返回提供给下一个插件管道使用。其中globs就是匹配格式,options是一些额外参数。

gulp.src('src/scss/master.scss')
    .pipe(sass())
    .pipe(gulp.dest('./dist’));

以上代码匹配master.scss文件返回给管道给sass插件进行编译操作,编译完成后送入下一个管道给gulp.dest接口输出到dist目录下。

globs
类型:字符串或者数组

此参数为文件匹配规则,例如./src/*/.scss将会匹配工作目录下src目录及子目录下所有scss文件格式的文件。字符匹配规则前带!则会排除此匹配的文件,例如:

gulp.src([
    'src/js/intro.js',
    'src/js/body.js',
    '!src/js/others.js',
    'src/hs/end.js'
]);

此将会按顺序匹配intro.js,body.js,end.js,排除了others.js

options
类型:对象

options.buffer (默认:true)
当设置为false的时候会把file.contents作为数据流(stream)返回而不是整个缓冲文件(buffer files),这个选项在处理较大文件的时候比较有效。但是:很多插件并不支持数据流处理。

options.read (默认:true)
当设置为false的时候并不会读取文件而且返回file.contents为空。

options.base (默认:匹配规则前的目录地址)
我们直接用代码演示吧:

gulp.src('src/js/**/*.js') //如果匹配到src/js/vendors/a.js, 那么base是src/js/
    .pipe(minify())
    .pipe(gulp.dest('dist')); //写入到dist/vendors/a.js

gulp.src('src/js/**/*.js', { base: 'src' }) //如果匹配到src/js/vendors/b.js
    .pipe(minify())
    .pipe(gulp.dest('dist')); //写入到dist/js/vendors/b.js

gulp.dest(path[, options])

此接口直接写入到文件里。(如果文件夹不存在则会创建对应文件夹)

gulp.src('src/js/body.js')
    .pipe(minify())
    .pipe(gulp.dest('dist/js')); //写入到dist/js/body.js

path
类型:字符串或者函数
具体输出目录或者一个函数返回目录

options
类型:对象

options.cwd(默认:process.cwd())
只有当输出路径为相对路径的时候才有效(一般用不到)

options.mode(默认:0777)
新建目录的权限(一般用不到)

gulp.task(name[, deps, fn])

定义一个需要自动执行的任务

gulp.task('sass', function() {
    gulp.src('src/scss/master.scss')
        .pipe(sass())
        .pipe(gulp.dest('dist/css'));
});
gulp.task('styles',['sass'], function() { 
    gulp.src('./dist/css/public.css') 
        .pipe(minifycss()) 
        .pipe(rename('public.min.css')) 
        .pipe(gulp.dest('dist/css'));
});

通过在终端运行gulp styles执行styles这个任务,此任务前先执行sass任务,完毕后再进行此任务,将public.css复制一份进行压缩并重命名为public.min.css到dist/css目录下。这里需要注意的是前提依赖任务如果有多个,一般它们并不会按照顺序执行,而是异步执行的。

gulp.watch(glob [, opts], tasks)或gulp.watch(glob [, opts, cb])

自动监视文件变化并执行指定的任务。

//监视'src/js/'目录下的所有js文件,如果有变动则立即执行uglify任务
gulp.watch('src/js/**/*/js', ['uglify']);
gulp.watch(glob[, opts, cb])

自动监视文件变化并执行回调函数。

event.type
类型:字符串
事件的类型,值为:added, changed, deleted.

event.path
类型:字符串
触发事件的文件地址

gulp.watch('js/**/*.js', function(event) {
  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});

第二节:实战项目

我们将会建立一个自动编辑scss文件及自动打包多个js文件的项目作为演示

安装配置

Gulp是依赖Node.js运行的,你必须先安装Node.js,然后在命令行下通过执行以下命令全局安装Gulp。

$ npm install --global gulp

在项目根目录下运行以下命令创建package.json文件(用来配置项目常规设置)

$ npm init

然后继续运行以下命令,依次下载Gulp及我们项目所需的依赖插件。

$ npm install --save-dev gulp
$ npm install --save-dev gulp-uglify
$ npm install --save-dev gulp-concat
$ npm install --save-dev gulp-autoprefixer
$ npm install --save-dev gulp-minify-css
$ npm install --save-dev gulp-rename
$ npm install --save-dev gulp-sass

在项目根目录下建立一个gulpfile.js文件作为Gulp任务程序,并按如下建立文件夹结构,dist的子目录不需要建立,在运行Gulp的时候会自动生成。

到此我们的项目结构会如下所示:

.
|—dist/
|-node_modules/
|—src/
| |—scss/
| |—master.scss
| |—_base.scss
|
|—js/
| |-intro.js
| |-body.js
| |-others.js
| |-end.js
|
|-package.json
|-gulpfile.js

然后我们来建立第一个默认任务吧,在gulpfile.js里输入以下代码:

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    concat = require('gulp-concat'),
    minifycss = require('gulp-minify-css'),
    uglify = require('gulp-uglify'),
    rename = require('gulp-rename'),
    autoprefixer = require('gulp-autoprefixer');

gulp.task('default', function() {
  // 将你的默认的任务代码放在这
});

在终端里运行$ gulp命令,默认名为default的任务将会被运行。但此时默认任务没有任何工作。

scss编译任务

下面我们添加一个scss编译任务,主要完成scss文件编译成css文件并进行多浏览器支持修正最后还要生成一个压缩版本的css文件。继续在gulpfile.js里添加如下代码:

gulp.task('sass', function() {
    gulp.src('./src/scss/**/*.scss') //匹配文件
    .pipe(sass({                       //sass模块编译
        outputStyle: 'expanded'
    }).on('error', sass.logError))
    .pipe(autoprefixer({               //进行浏览器兼容
        browsers: ['last 10 versions']
    }))
    .pipe(gulp.dest('./dist/css'))     //输出一份到dist/css目录
    .pipe(minifycss())                 //继续压缩一份
    .pipe(rename("public.min.css"))    //重命名避免覆盖上一次的输出
    .pipe(gulp.dest('./dist/css'));    //输出压缩好的新css文件
});

在终端运行$ gulp sass,将会执行名称为sass的任务,会自动完成我们上面所说的功能。

js打包任务

我们继续添加一个自动合并js文件并压缩的任务,继续在gulpfile.js里添加如下代码:

gulp.task('scripts', function() {
    gulp.src([
        './src/js/intro.js',
        './src/js/body.js',
        './src/js/end.js'
    ])
    .pipe(concat('app.js'))         // 合并为一个文件
    .pipe(gulp.dest('./dist/js'))   // 写入一份到指定目录
    .pipe(uglify())                 // 压缩一份
    .pipe(rename("buldle.min.js"))  // 并重命名以防覆盖上次写入的文件
    .pipe(gulp.dest('./dist/js'));  // 写入到指定目录
});

在终端运行$ gulp scripts,将会执行名称为scripts的任务,会自动完成我们上面所说的功能。

监视自动化处理

下面我们来修改默认任务,让每当执行默认任务的时候,自动执行sass与scripts这两个任务,修改default任务代码如下:

gulp.task('default', ['sass', 'scripts']);

这样,在终端运行$ gulp的时候,就会自动运行sass与scripts这两个任务了。

但每次修改以下scss文件或者js文件都要去运行一次$ gulp命令岂不是很麻烦,这里我们就要用到gulp的gulp.watch接口来自动监视文件的变化并运行指定的任务,这样我们就不要手动的去运行命令了。继续添加以下代码:

gulp.task('watcher', function() {
    gulp.watch("src/scss/**/*.scss", ['sass']);
    gulp.watch("src/js/*.js", ['scripts']);
});

这里我们添加了一个名为watcher的任务,当在终端运行$gulp watcher命令后,Gulp将会自动监视我们匹配文件的变化,每当文件改变了就会自动运行指定的任务。

到此,我们这个项目的Gulp配置都完成了,每当我们需要进行项目开发的时候,只需要在终端执行$ gulp watcher后,Gulp就会自动在后台监视运行了,我们只需要好好写代码,其他的编译任务将会自动运行了。

项目代码下载:gulp-project

其他文献:

https://github.com/gulpjs/gulp/blob/master/docs/API.md (官方接口API文档)
https://github.com/gulpjs/gulp/tree/master/docs/recipes (很多演示项目代码)
https://github.com/gulpjs/gulp/blob/master/docs/README.md#articles (其它Gulp教程文章)


墨鱼
488 声望8 粉丝

I READ, I CODE, I WRITE.