另一种前端自动化工具-gulp

之前说到过grunt以及FIS,在项目里也用到过!因为最近组里又推荐用gulp,于是在这记录一番:

假设我们项目的目录为:

├── src
│ ├── index.html
│ ├── images
│ ├── script
│ └── css

所谓的自动化就是将src里的文件,通过压缩、合并以及各种优化处理,然后生成一个可以发布到生产环境(假设生成目录为dest)。

├── src
│ ├── index.html
│ ├── images
│ ├── script
│ └── css
├── dest

在开始之前,我们在项目根目录新建package.json,通过 npm init

gulp安装

全局安装

npm install gulp -g

本地安装

npm install gulp —-save-dev

版本查看

gulp -v

若只是全局安装,则无法处理文件~
—-save-dev 这个选项,会将gulp安装添加到package.json中。当安装完后,你会在package.json中看到有关gulp的依赖

在项目根目录创建gulpfile.js文件,最终目录如下:

目录如下:

├── node_modules
│ └── gulp
├── src
│ ├── index.html
│ ├── images
│ ├── script
│ └── css
├── gulpfile.js
└── package.json

gulp.js语法

我们使用gulp,是通过gulpfile.js文件来配置的。首先在这个文件里引入gulp:

var gulp = require("gulp");

然后通过gulp里定义的API方法来处理各种文件。以下做分别介绍:

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

这个方法定义了一个任务管理,它包括三个参数,

name : 任务名称

gulp.task('taskname', function() {
  // 通过命令 gulp taskname,执行任务
});

需要注意的是,你可以将任务名称定义为 default,即gulp的默认命令。这样你就无需在gulp后加任务名称,直接通过 gulp 就能执行相关的操作任务

gulp.task('default', function() {
  // 通过命令 gulp,执行任务
});

deps : 一个数组。会在执行完这个数组里的任务后,再执行当前任务

gulp.task('taskname', ['task1', 'task2'], function() {
  // 通过命令 gulp taskname,先执行task1和task2,再执行taskname
});

fn : 回调函数。当前任务需要做的事

gulp.task('taskname', function() {
	//do something
	console.log('taskname运行完成!');
});

而关于多个任务的运行。可以先定义多个任务,然后将多个任务添加到一起,然后直接指向默认任务。

gulp.task('taskname1', function() {
	//do something
	console.log('taskname1运行完成!');
});
 
gulp.task('taskname2', function() {
	//do something
	console.log('taskname2运行完成!');
});
 
// 通过命令 gulp,执行taskname1和taskname2
gulp.task('default', ['taskname1', 'taskname2']);

gulp.src(globs[, options])

这个方法指定了需要操作文件。

globs : 需要处理文件的路径。数据类型为字符串或数组

options : 可选参数。值为一个对象,有buffer、read、base三个属性
options.buffer,布尔值,默认true。当设置为false时,返回file.content的流并且不缓冲文件,处理大文件时非常有用;
options.read,布尔值,默认true。当设置false时,将不执行读取文件操作,返回null;
options.base,字符串。设置输出路径以某个路径的某个组成部分为基础向后拼接

有关glob的匹配模式

* 匹配文件路径中的0个或多个字符,但不会匹配路径分隔符,除非路径分隔符出现在末尾
** 匹配路径中的0个或多个目录及其子目录,需要单独出现,即它左右不能有其他东西了。如果出现在末尾,也能匹配文件。
? 匹配文件路径中的一个字符(不会匹配路径分隔符)
[...] 匹配方括号中出现的字符中的任意一个,当方括号中第一个字符为^或!时,则表示不匹配方括号中出现的其他字符中的任意一个,类似js正则表达式中的用法
!(pattern|pattern|pattern) 匹配任何与括号中给定的任一模式都不匹配的
?(pattern|pattern|pattern) 匹配括号中给定的任一模式0次或1次,类似于js正则中的(pattern|pattern|pattern)?
+(pattern|pattern|pattern) 匹配括号中给定的任一模式至少1次,类似于js正则中的(pattern|pattern|pattern)+
*(pattern|pattern|pattern) 匹配括号中给定的任一模式0次或多次,类似于js正则中的(pattern|pattern|pattern)*
@(pattern|pattern|pattern) 匹配括号中给定的任一模式1次,类似于js正则中的(pattern|pattern|pattern)

比如以下是匹配src下所有的css文件,然后再进行压缩:

gulp.task('minify-css', function () {
    gulp.src('src/**/*.css')  
    	.pipe(minifyCss()) 
    	.pipe(gulp.dest('dest'));
});

gulp.dest(path[, options])

这个方法指定处理完文件的输入路径。如果指定的目录不存在,则会直接新建文件目录,但gulp.dest不能修改操作完文件的名称。

path : 字符串或函数。文件的具体路径或函数运行后返回的路径

options : 可选参数。值为一个对象,有cwd、mode两个属性
options.cwd,字符串。输出目录的 cwd 参数,只在所给的输出目录是相对路径时候有效;
options.mode,字符串。用以定义所有在输出目录中所创建的目录的权限,默认值为0777;

来看个例子,以下代码的作用是将src里的文件生成到dest目录里,中间未对文件做任何处理。

gulp.task('output', function () {
	gulp.src('src/**')
    	.pipe(gulp.dest('dest'))
   console.log("将src文件输出到dest目录!");   
});

关于base路径匹配与生成,以下的例子src中的base为 src/less:

gulp.task('output', function () {
	// base的值为src/less
	gulp.src('src/less/*')
    	.pipe(gulp.dest('dest'))
   console.log("dest会替换src/less");   
});

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

gulp.watch用于监听文件,当被监听的文件修改时,浏览器会自动刷新。

glob : 匹配到的具体文件。一个字符串或者数组

opts : 一个对象

cb : 监听文件发生改变后的操作函数,该参数传入一个对象参数,它包含两个属性
event.type : 字符串。对应的值有added, changed 或者 deleted
event.path : 字符串。触发事件文件所在的路径

gulp.task('watch', function() {
	// 监听less文件,若有改动,执行css任务
	gulp.watch('src/**/*.less', ['css']);	
})
gulp.watch('js/app.js', function (event) {
   console.log('Event type: ' + event.type); // added, changed, or deleted
   console.log('Event path: ' + event.path); // The path of the modified file
});

在了解gulp相关方法后,我们知道,它们的作用主要是引用、监控以及输出需要处理的文件。但我们中途还需要对文件进行相关处理,那就需依赖各种插件。

相关插件

文章最后列出了gulp比较常用的插件,注意在使用它们之前,如上所说需先引入 gulp = require(‘gulp’),

gulp-minify-html 压缩html

安装:npm install gulp-minify-html –save-dev

var minifyHtml = require("gulp-minify-html");
gulp.task('minify-html', function () {
    gulp.src('src/*.html') 
    	.pipe(minifyHtml()) 
    	.pipe(gulp.dest('dest'));
});

gulp-minify-css 压缩css

安装:npm install gulp-minify-css –save-dev

var minifyCss = require('gulp-minify-css');
gulp.task('minify-css', function () {
    gulp.src('src/**/*.css')  
    	.pipe(minifyCss()) 
    	.pipe(gulp.dest('dest'));
});

gulp-less 编译less

安装:npm install gulp-less –save-dev

var less = require('gulp-less');
gulp.task('less', function () {
    gulp.src('src/less/*.less')
    	.pipe(less())
    	.pipe(gulp.dest('dest/css'));
});

gulp-ruby-sass 编译sass

安装:npm install gulp-ruby-sass –save-dev

var sass = require('gulp-ruby-sass');
gulp.task('sass', function () {
    return sass('src/sass/*.scss',{ sourcemap: false })
		    .on('error', sass.logError)
		    .pipe(gulp.dest('dest/css'));	
});

gulp-autoprefixer 补全浏览器兼容的css

安装:npm install gulp-autoprefixer –save-dev

var autoprefixer = require('gulp-autoprefixer');
gulp.task('autoprefixer', function () {
    return gulp.src('src/**/*.css')
        .pipe(autoprefixer({
            browsers: ['last 2 versions'],
            cascade: false
        }))
        .pipe(gulp.dest('dest'));
});

gulp-uglify 压缩js

安装:npm install gulp-uglify –save-dev

var uglify = require('gulp-uglify');
gulp.task('uglify', function () {
    gulp.src('src/**/.js') 
    	.pipe(uglify())  
    	.pipe(gulp.dest('dest')); 
});

gulp-concat 合并js以及css文件

安装:npm install gulp-concat –save-dev

var concat = require('gulp-concat'); 
gulp.task('concat', function () {
    gulp.src('src/**/*.js')  
    	.pipe(concat('app.js')) 
    	.pipe(gulp.dest('dest/js'));
});

gulp-imagemin 图片压缩

安装:npm install gulp-imagemin –save-dev
npm install imagemin-pngquant –save-dev

var imagemin = require('gulp-imagemin'),
	pngquant = require('imagemin-pngquant');
gulp.task('imagemin', function () {
    gulp.src('src/img/*')
        .pipe(imagemin({
            progressive: true,
            use: [pngquant()] 
        }))
        .pipe(gulp.dest('dest/img'));
});

gulp-rename 重新命名

安装:npm install gulp-rename –save-dev

var uglify = require('gulp-uglify'),
    rename = require('gulp-rename');
gulp.task('rename', function () {
    gulp.src('src/**/*.js')
    	.pipe(uglify()) 
    	.pipe(rename({
    		extname: ".min.js"
    	}))
    	.pipe(gulp.dest('dest'));
});

browser-sync 自动刷新

类似gulp-livereload。与gulp-livereload不同的是,针对css的修改,浏览器只更新当前开发界面,而不会重新加载回到页面的第一个界面,因此也无需依次点“下一步”跳到当前开发的界面。

安装:npm install browser-sync –save-dev

var browserSync = require('browser-sync');
gulp.task('browser-sync', function () {
   var files = [
      'src/**/*.html',
      'src/**/*.css',
      'src/**/*.png',
      'src/**/*.js'
   ];
 
   browserSync.init(files, {
      server: {
         baseDir: './src'
      }
   });
});

参考:1. https://github.com/sindresorhus/gulp-imagemin
2. https://www.npmjs.com/package/gulp-rename
3. https://www.browsersync.io/docs/gulp/
4. http://www.cnblogs.com/2050/p/4198792.html

评论功能已关闭。