Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

比Grunt更好用的前端自动化工具——Gulp #3

Open
pb-cheung opened this issue Nov 18, 2015 · 0 comments
Open

比Grunt更好用的前端自动化工具——Gulp #3

pb-cheung opened this issue Nov 18, 2015 · 0 comments

Comments

@pb-cheung
Copy link
Owner

比Grunt更好用的前端自动化工具——Gulp

logo

  • 前端构建工具
  • 基于node.js
  • 流式

一、安装

全局安装:

npm install -g gulp

项目目录中安装:

nmp install --save-dev gulp

编辑package.json文件,
或者执行

npm init 

生成package.json,然后执行

npm install

二、API

gulp和插件安装完毕后,
在目录中创建配置文件gulpfile.js。

gulp.src()

指定数据源文件,产生数据流。参数是文件,可以是数组

gulp.src(["js/**/*.js",[!js/**/*.min.js]])

gulp.dest()

将管道的输出写入文件,同事将这些输出继续输出,因此可以多次调用dest方法,将输出写入多个目录。目录不存在则新建。

gulp.task()

用于任务定义。第一个参数是任务名称,第二个参数是任务函数,指定任务具体的操作。

task方法还可以指定按顺序运行的一组任务,例如:

gulp.task("build",["css","js","imgs"]);

上例中,定义一个任务build,执行三个子任务“css”、“js”、“imgs”。这些任务不是同时进行的,不能认为“js”任务结束时“css”任务已经结束。

如果需要确保一个任务在另一个任务结束后执行,可将函数和任务组合结合起来指定依赖关系。例如:

gulp.task("css",["greet"], function(){
    //
});

上例中,定义“css”任务,执行前检查greet任务是否执行完毕,完毕在调用第三个参数定义的函数。

default tasks
执行gulp任务是在命令行中输入:

gulp + taskName

如果不加taskName,就会报“Task ‘default’ is not in your gulpfile”,找不着默认任务。最好在配置文件末,写上默认任务,执行起来比较方便。例如:

gulp.task("scripts",function(){
    //...
});

...

gulp.task("default", ["scripts"]);

gulp.watch()

监听文件的状态,文件发生变化执行某些任务。
用法:

gulp.task("watch",function(){
    gulp.watch("js/src/**/*.js",["copy","concat","uglify"])
})

上例中任务数组可以换成回调函数,

gulp.task("watch",function(){
    gulp.watch("js/src/**/*.js",function(event){
        console.log("Event type: " + event.type + " Event path" + event.path);
    })
})

回调函数中打印事件类型和发生改变文件路径,type值有“added”、“deleted”、“changed”

gulp.watch可配合LiveReload、BrowserSync使用,实现文件修改浏览器立即刷新等功能

三、插件

http://gulpjs.com/plugins/

常用操作 插件名称
文件合并 gulp-concat
文件拷贝 gulp-copy
文件替换 gulp-replace
JS压缩 gulp-uglify
语法检查 gulp-jshint
图片压缩 gulp-imagemin
CSS压缩 gulp-cssmin
添加注释 gulp-wrapper

压缩JS gulp-uglify

https://www.npmjs.com/package/gulp-uglify

举个栗子:

var gulp = require("gulp"),
    uglify = require("gulp-uglify");
gulp.task("uglify",function(){
    gulp.src(["src/common/*.js"])
    .pipe(uglify({
        mangle: {
            except: ["define","require","module","exports"]
        }
    }))
    .pipe(gulp.dest("min/common"))
});

上例中,将src/common/目录下的js进行压缩,压缩文件放到min/common/目录中。参数mangle,可以像上例中那样排除一些关键字以适用sea.js模块管理,或者赋值“false”,在压缩过程中跳过函数名使其不被压缩。

mangle

合并 gulp-concat

https://www.npmjs.com/package/gulp-concat

例子:

var gulp = require("gulp"),
    concat = require("gulp-concat"),
    uglify = require("gulp-uglify");
gulp.task("scripts",function(){
    gulp.src(["src/common/reqData.js","src/common/util.js"])
    .pipe(uglify())
    .pipe(concat("base.min.js",{
        newLine: "\r\n\r\n"
    }))
    .pipe(gulp.dest("min/common"))
});

上例中,将src/common/目录下reqData.js和util.js压缩后合并成一个文件base.min.js,参数的作用是在两个文件之间添加两个换行。

四、Stream

类似于*nix将几乎所有的设备抽象为文件一样,Node将文件访问、输入输出、http连接等几乎所有I/O都抽象成了Stream。

Linux中管道的概念

管道命令的处理示意图

通过管道将stdout导入到stdin。command1的正确输出(stand output)作为command2的输入,然后command2的输出作为command3的输入,command1、2的输出不会显示,command3的运行结果会输出。
可以类比理解。shell中的“|”符号和gulp中的pipe()方法作用相同。

gulp翻译

五、其他高级用法

gulp.env

gulp有个env属性可以接受参数,env属性值对应一个对象:

{ _ : [] }

"_"属性值默认是空,当指定执行任务时,它的值是任务名。
例如:

gulp compress

gulp.env是:

{ _ : ["compress"]}

同理指定多个任务,数组中就有多个值。可以获取这些任务名来执行不同的操作,例如根据任务名不同来修改不同目录

命令行传参

用法:

gulp --key1 value1 --key2 value2

获取方式和上面类似,通过gulp.env

gulp.env: { _ : [], key1: value1, key2: value2 }

针对参数使用举个例子:

var gulp = require("gulp"),
    uglify = require("gulp-uglify"),
    header = require("gulp-header"),
    gutil = require("gulp-util");

var dir = gulp.env.dir ? gulp.env.dir : "common",
    date = (new Date()).getTime();

gulp.task("default",function(){
    gutil.log(gutil.colors.bgGreen("/* ------- 用 法 ------- */"));
    gutil.log(gutil.colors.bgGreen("拷贝:gulp copy --dir [目录名]"));
    gutil.log(gutil.colors.bgGreen("压缩:gulp jsmin --dir [目录名] "));
});

gulp.task("copy",function(){
    return gulp.src("src/" + dir + "/*.js")
    .pipe(header("/* timeStapmp="+ date +" */ \r\n"))
    .pipe(gulp.dest("min/" + dir))
});

gulp.task("jsmin",function(){
    return gulp.src("src/" + dir + "/*.js")
    .pipe(uglify())
    .pipe(header("/* timeStapmp="+ date +" */ \r\n"))
    .pipe(gulp.dest("min/" + dir))
});

执行:
执行结果
上例中,定义了两个任务"copy"和“jsmin”,两个任务都能接受一个参数,这个参数指定操作对应的目录。

六、与Grunt比较

与Grunt对比

比Grunt配置少配置简单、运行速度快

  • 不生成中间文件

Gulp基于node.js的Stream机制。每个插件不能单独使用,依靠组合发挥作用,就像一条流水线,上一道工序的产出交给下一道工序,效率高。
Grunt基于文件,很多操作都要需要生成一些中间文件,这些文件在任务完成后就没用了,需要删掉。文件操作时间消耗多,还有无用文件产生。gulp配置代码量相应的也会少。

  • 配置和运行在一起

变量的声明和使用挨在一起最方便。但是Gruntfile中,配置task和调用一般都离得很远,尤其是配置文件比较大的时候。

  • 插件配置语法基本相同

Grunt的很多插件的配置规则有一定差别,有的看起来还有些怪异。Gulp插件配置规则基本都一样。(插件方法调用,第一个参数是文件,第二个是配置json。)

  • 每个插件只专注于做一件事情

Gulp中每个插件单一职责,每个插件的配置就比较简单。
Grunt中每个插件要配置一坨。

七、参考

Gulp开发教程

gulp plugin 插件介绍

Node中的流

鸟哥 管道命令

Gulp挑战Grunt背后的哲学

gulp传参数 实现定制化执行任务

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant