常用开发工具介绍(三)Grunt

前言

Grunt是一个基于任务的JavaScript工程命令行构建工具。对于需要反复重复的任务,例如压缩、编译、单元测试等工作,自动化工具可以将你解放出来,节省你的时间提高你的效率。使用Grunt你只要正确的配置好任务,任务运行器就会自动完成大部分无聊的工作。Grunt生态系统拥有数量庞大的插件可供选择,因此你可以利用Grunt自动完成很多的事。

安装

Grunt和 Grunt插件是通过 Node.js 的包管理器npm安装和管理的。

Grunt0.4.x必须在Node.js0.8.0以上版本使用。

Grunt

在安装Grunt前,最好升级npm至最新版本:

1
root@localhost:~# npm update -g npm

安装CLI到全局环境下,命令如下:

1
root@localhost:~# npm install -g grunt-cli

注: CLI的任务很简单:调用与Gruntfile在同一目录中Grunt。这样做的好处是,你可以在同一个系统上同时安装多个版本的Grunt。

安装命令如下:命令将安装Grunt最新版本到项目目录中:

1
root@localhost:~# npm install grunt --save-dev

Grunt的插件,也可以通过这种方式安装,例如安装JSHint任务模块:

1
root@localhost:~# npm install grunt-contrib-jshint --save-dev

安装插件之后,要确保将更新之后的package.json文件提交到项目中。

使用

使用时需要在你的项目中添加两份文件:package.json 和 Gruntfile。这两个文件应当放置于项目的根目录下。

  • package.json: 用于存储项目的基础数据,以便你的项目发布成npm模块。你可以在此文件中列出项目依赖的grunt和Grunt插件,放在devDependencies配置段中。

  • Gruntfile: 文件命名为Gruntfile.js(JavaScript文件)或Gruntfile.coffee(coffeeScript文件),用来设置任务(task)及加载Grunt插件。Gruntfile由以下几部分构成:

    • “wrapper” 函数
    • 项目与任务配置
    • 加载grunt插件和任务
    • 自定义任务 下面是一个典型的Gruntfile案例,package.json文件中的metadata被导入到Grunt配置中, grunt-contrib-uglify插件中的uglify任务被设置为压缩源码文件并根据metadata动态生成一个注释。在命令行中执行grunt时,uglify任务会被默认执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module.exports = function(grunt) {

// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
}
});

// 加载包含 "uglify" 任务的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');

// 默认被执行的任务列表。
grunt.registerTask('default', ['uglify']);

};

上面案例文件的详细含义是:

  • wrapper” 函数

Gruntfile和Grunt的插件在编写Grunt代码是都需要放在这个函数内:

1
2
3
module.exports = function(grunt) {
// Do grunt-related things in here
};

  • 项目和任务设置

Grunt任务都依赖各种设置,这些需要设置的值被定义在一个json对象内,然后传递给grunt.initConfig方法就ok了。

在下面的案例中,grunt.file.readJSON(‘package.json’)把存在package.json文件中的JSON数据引用到grunt的设置中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
//用于在文件顶部生成一个注释
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
//将一个js文件压缩为一个目标文件。
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
}
});

  • 加载 Grunt 插件和任务

像 concatenation(合并文件)、minification(压缩)、grunt-contrib-uglify(最小化js)和linting(代码走查)这些常用的任务,都已经有grunt插件了。只要在package.json文件中被列为dependency包,并通过npm install安装就好,在Gruntfile中以命令的形式使用:

1
2
// 加载能够提供"uglify"任务的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');

  • 自定义任务

通过设置default任务,可以让Grunt默认执行一个或多个任务。在下面的这个案例中,执行 grunt 命令时如果不指定一个任务的话,将会执行uglify任务。这和执行grunt uglify或者 grunt default没什么差别。default任务列表数组中可以指定任意数目的任务(可以带参数)。

1
2
// Default task(s).
grunt.registerTask('default', ['uglify']);

如果Grunt插件中的任务不能满足你的项目需求,你还可以在Gruntfile中自定义任务。例如,在下面的 Gruntfile中自定义了一个default 任务,并且不依赖任务配置:

1
2
3
4
5
6
7
8
module.exports = function(grunt) {

// A very basic default task.
grunt.registerTask('default', 'Log some stuff.', function() {
grunt.log.write('Logging some stuff...').ok();
});

};

特定于项目的任务不必在Gruntfile 中定义。他们可以定义在外部.js文件中,并通过grunt.loadTasks方法加载。