使用Grunt进行前端自动化构建

先来看下我们的一些开发场景:

项目开始前:

新建项目文件夹,创建js,images,css文件夹;拷贝js库(jquery,seajs等)和css库(bootstrap等)进入相关的文件夹,再新建各个文件。

写代码中:

编辑器编码 --> 切换到浏览器F5 --> 编辑器编码 --> 切换到浏览器F5 --> 编辑器编码 --> 切换到浏览器F5 ......

编码完成:

HTML去掉注析、换行符

CSS文件压缩合并

JS代码风格检查

JS代码压缩

image压缩

这么多重复的工作,简直是太浪费时间了。为了解决这些问题, Grunt应运而生。

Grunt是javascript的一个自动化构建工具,你可以用它来做一些重复的任务,比如压缩、编译、单元测试、linting等,配置好Grunt的配置文件Gruntfile.js,你就可以专心地去写代码了。

一些链接:

  • 官网: http://gruntjs.com/
  • Github: https://github.com/gruntjs

本指南使用的grunt版本是v0.4.5

安装

Grunt的组成

Grunt有三大主要组成部分:

  • Gruntjs CLI: GruntJS的命令行工具,用于调用与Gruntfile在同一目录中的Grunt。
  • Grunt: 用于执行任务。
  • Grunt Plugins: Grunt的很多任务都是通过安装不同的插件去实现。

Grunt CLI与Grunt是分离的, 安装Grunt CLI不等于安装了Grunt。一般都是全局安装Grunt CLI,而在项目目录中安装Grunt。

这样就能让多个版本的 Grunt 同时安装在同一台机器上,同时确保每个团队的成员在同一项目使用同一版本的Grunt,避免未来不同项目对Grunt不同版本的依赖关系。

安装Grunt

1)升级npm

可以通过npm安装Grunt,nodejs的版本必须要>=0.8.0。在开始安装Grunt之前,先升级npm:

1
$ npm update -g npm

或者:

1
$ npm install -g npm@latest

2)安装grunt-cli

全局安装Grunt CLI:

1
2
$ npm install -g grunt-cli
$ grunt --version

**注:**安装了Grunt CLI并不等于安装了Grunt

3)安装grunt

Grunt作为项目的开发依赖进行安装。在你的项目目录安装:

1
2
$ npm install grunt --save-dev
$ npm install grunt@0.4.5 --save-dev # 指定安装的版本

开始使用

现在来开始使用Grunt。我们以使用jshint为例。

首先安装好jhsint以及Grunt的jshint插件:

1
2
$ npm install -g jshint
$ npm install --save-dev grunt-contrib-jshint

然后在项目根目录下新建Grunt的配置文件Gruntfile.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14

module.exports = function(grunt) {

// 配置Grunt各种模块的参数
grunt.initConfig({
jshint: [‘Gruntfile.js’]
});

// 从node_modules目录加载模块文件
grunt.loadNpmTasks('grunt-contrib-jshint');

// 注册check别名,执行jshint任务
grunt.registerTask('check', ['jshint']);
};

在命令行执行:

1
$ grunt check

这样我们就可以通过grunt去使用jshint来检查javascript代码了。

应用

为了更好地管理grunt的任务,我不把所有的task配置都写在Gruntfile.js,而是把各个任务的配置分离到不同的配置文件。这需要使用到插件load-grunt-tasks,它会自动读取并加载项目packge.json文件中devDependencies配置下以grunt-*开头的依赖库。。

1
$ npm install load-grunt-tasks --save-dev

然后,可以这样写Gruntfile.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var glob = require('glob'),
path = require('path'),
join = path.join;

module.exports = function(grunt) {

var config = {
pkg: grunt.file.readJSON('package.json'),
};
grunt.util._.extend(config, loadConfig('./grunt/options/'));
grunt.initConfig(config);

require('load-grunt-tasks')(grunt);

grunt.loadTasks('grunt');
};

function loadConfig(configPath) {
var config = {};

glob.sync('*', { cwd: configPath })
.forEach(function(configFile) {
var prop = configFile.replace(/\.js$/, '');
config[prop] = require(join(__dirname, configPath, configFile));
});

return config;
}

同时,新建grunt/文件夹,结构如下:

具体的每个task放options/文件夹下面。例如:

browserify.js

1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports = exports = {
dist: {
options: {
"transform": [["babelify", { "presets": ["es2015"] }]]
},
files:[{
expand: true,
cwd: 'dev/',
src: ['**/*.js', '!lib/**/*.js'],
dest: 'dist/',
}]
}
};

这样使用是不是觉得很清爽,并且非常容易维护?

参考: More maintainable Gruntfiles

配置文件说明

Grunt配置

Gruntfile.js分几个部分:

"wrapper" 函数

每一份 Gruntfile (和grunt插件)都遵循同样的格式,你所书写的Grunt代码必须放在此函数内:

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

项目与任务配置

大部分的Grunt任务都依赖某些配置数据,这些数据被定义在一个object内,并传递给grunt.initConfig方法。如:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 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'
}
}
});

加载grunt插件和任务

很多常用的任务(task)都已经以grunt插件的形式被开发出来了。

使用的时候,用npm install安装之后,都可以在Gruntfile.js中以下面的简单命令形式加载使用:

1
2
3
4
5
6
// 加载能够提供"uglify"任务的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');

自定义任务

以下方式可以定义任务:

1
2
3
grunt.registerTask('default', ['jshint','uglify']);
grunt.registerTask('dev', ['watch']);
grunt.registerTask('prod', ['create']);

然后在命令行就可以执行任务:

1
2
3
$ grunt
$ grunt dev
$ grunt prod

任务的更详细的配置参考: http://gruntjs.com/creating-tasks

grunt进行ES6的模块化编译的时候,速度太慢了,已经转用了gulp,那速度简直是杠杠的。

文章目录
  1. 1. 安装
    1. 1.1. Grunt的组成
    2. 1.2. 安装Grunt
  2. 2. 开始使用
  3. 3. 应用
  4. 4. 配置文件说明
    1. 4.1. "wrapper" 函数
    2. 4.2. 项目与任务配置
    3. 4.3. 加载grunt插件和任务
    4. 4.4. 自定义任务
,