前言
该系列文章就是直接翻译 http://gruntjs.com/getting-started 中的内容,摘要重要的内容,过程中给出自己的理解。加深记忆。
备注:另外一款gulp
和 grunt 同样是做构建工作的,虽然最终的目的相同,但是过程中的侧重点不同,gulp
构建过程的侧重点是基于并发,而 grunt 是侧重依次执行;见分析文章,http://sixrevisions.com/web-development/grunt-vs-gulp/ 其实,grunt 也支持并发,但是需要在定义 task 的时候明确指定,而 gulp 天生就是为并发而创建的。
靠,居然发现一个中文网站 http://www.gruntjs.net/getting-started
Grunt 是什么
一句话,grunt 就是类似于构建 java 的 maven 这样的构建工具,用来构建 javascript 工程的。Grunt可以执行像压缩, 编译, 单元测试, 代码检查以及打包发布的任务。注意,这里有别于 npm,NPM 是用来构建 NodeJs 工程的,而 grunt 是用来构建诸如使用 angularjs,jquery 等工具开发的项目工程的,两者虽然都是类似于 maven 这样的构建工具,但是服务的对象不同。
Grunt常用插件:
- grunt-contrib-uglify:压缩js代码
- grunt-contrib-concat:合并js文件
- grunt-contrib-qunit 或者 jasmine:单元测试
- grunt-contrib-jshint:js代码检查
- grunt-contrib-watch:文件监控
Grunt CLI
Grunt CLI 安装
全局安装grunt-cli
,1
npm install -g grunt-cli
- This will put the grunt command in your system path, allowing it to be run from any directory.
他会将 grunt 添加到你的系统目录,允许在任何目录中被调用。 - Note that installing grunt-cli does not install the
Grunt task runner
,
注意,grunt-cli 并没有安装Grunt task runner
,也就是说,它并不是 Grunt 的执行器。 - his job of the Grunt CLI is simple: run the version of Grunt which has been installed next to a Gruntfile. This allows multiple versions of Grunt to be installed on the same machine simultaneously.
它的职责很简单,启动 Gruntfile 中指定的 Grunt 版本,也因此,允许多个不同版本的 Grunt 被同时安装在一台机器上。
Grunt CLI 如何加载不同版本的 Grunt 的?
Each time grunt is run, it looks for a locally installed Grunt using node’s require() system. Because of this, you can run grunt from any subfolder in your project.
If a locally installed Grunt is found, the CLI loads the local installation of the Grunt library, applies the configuration from your Gruntfile,read the code
简而言之,就是,每当应用启动的时候,从Gruntfile
中读取配置并通过required()
方法从系统中获取对应版本的Grunt
。
Working with an existing Grunt project
Assuming that the Grunt CLI has been installed and that the project has already been configured with a package.json
and a Gruntfile
(Gruntfile.js or Gruntfile.yaml), it’s very easy to start working with Grunt:
- Change to the project’s root directory.
- Install project dependencies with
npm install
. - Run Grunt with
grunt
.
备注,这里执行的是grunt default
,执行默认 task
That’s really all there is to it. Installed Grunt tasks can be listed by running grunt --help
but it’s usually a good idea to start with the project’s documentation. 对的,一个grunt project
其实就是这三步即可,也就可以实施对一个grunt project
的整个生命周期的构建行为了。这就是Grunt
的强大之处了。
Preparing a new Grunt project
A typical setup will involve adding two files to your project: package.json
and the Gruntfile
.
package.json
: This file is used by npm to store metadata for projects published as npm modules. You will list grunt and the Grunt plugins your project needs as devDependencies
in this file.
Gruntfile
: This file is named Gruntfile.js
or Gruntfile.coffee
and is used to configure or define tasks and load Grunt plugins. When this documentation mentions a Gruntfile it is talking about a file, which is either a Gruntfile.js or a Gruntfile.coffee.
package.json
The package.json
file belongs in the root directory of your project, next to the Gruntfile
, and should be committed with your project source. Running npm install
in the same folder as a package.json
file will install the correct version of each dependency listed therein.
There are a few ways to create a package.json
file for your project:
- Most grunt-init templates will automatically create a project-specific
package.json
file. - The npm init command will create a basic package.json file.
- Start with the example below, and expand as needed, following this specification.
这步其实是手动创建,根据package.json specification的定义手动创建,
上面描述了如何创建 package.json 的三种方式,不过grunt-init
有更多的内容,它主要是根据已有的工程模板去创建一个grunt 工程
,当然里面附带了所必须的package.json
;更多内容 npm 章节中的 package.json 的描述
Installing Grunt and Grunt Plugins
注意,Grunt
本身也是一个插件。
The easiest way to add Grunt and gruntplugins to an existing package.json
is with the command npm install <module> --save-dev
. Not only will this install <module>
locally, but it will automatically be added to the devDependencies section, using a tilde version range. (补充,如果使用 npm install <module> -save
将会添加到 package.json 中的 dependencies 中)
For example, this will install the latest version of Grunt in your project folder, adding it to your devDependencies:1
$ npm install grunt --save-dev
The same can be done for gruntplugins and other node modules. As seen in the following example installing the JSHint task module:1
npm install grunt-contrib-jshint --save-dev
Checkout the current available gruntplugins to be installed and used on your project at the plugins page.
Be sure to commit the updated package.json file with your project when you’re done!
以上是官方内容的原文,以下给出自己的理解,
grunt
本身就是 nodejs 的一个模块,通过 npm
管理和安装。安装方式如下所述,
npm install grunt
1
>> npm install grunt
将会安装最新版本的
grunt
模块到本地工程根目录的.node_modules
目录中。npm install grunt –save-dev
1
>> npm install grunt --save-dev
不但会安装 grunt 模块,还会自动将该模块添加添加到
package.json
的devDependencies
中。另外,若执行npm install grunt --save
将会将模块添加到package.json
的dependecies
中通过 package.json 的依赖关系进行安装
在 package.json 中定义好 grunt 模块的依赖关系,然后grunt install
即可安装。参考手动创建 Package.json
The Gruntfile
Gruntfile 和 package.json 一样,放置在项目的根目录当中,并且作为源码提交到代码版本管理器中,Gruntfile
由如下部分组成
- The “wrapper” function
- Project and task configuration
- Loading Grunt plugins and tasks
- Custom tasks
1 | module.exports = function(grunt) { |
The wrapper function
The wrapper function,任何的 grunt 代码都必须在该方法中定义。1
2
3module.exports = function(grunt) {
// Do grunt-related things in here
};
pkg 参数
从package.json
中加载元数据,并将其命名为pkg
参数,这样的话,通过pkg
就可以访问到 package.json 中的 json 元素,1
pkg: grunt.file.readJSON('package.json'),
定义模块的行为
定义grunt-contrib-uglify
模块的行为,uglify
模块的默认行为就是对 javascript 进行压缩,去掉注释,空格符等。然后自动生成 banner 注释。由此可以看到,实际上,Gruntfile 就是定义 Grunt 的执行行为,options1
2
3
4
5
6
7
8
9uglify: {
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')
的方式加载
;1
2// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
自动加载
有些时候,挨个手动的去加载比较麻烦,当模块比较多的时候,也比较容易出错,我们可以使用 jit-grunt 模块 实现模块的自动加载(备注,我是从 yeoman 生成的 angular 项目的 Gruntfile.js 中发现它的)
安装
jit-grunt
模块1
$ npm install jit-grunt --save-dev
在
Gruntfile.js
中的wrapper
中添加1
2
3
4
5
6
7
8
9
10
11
12module.exports = function (grunt) {
// Automatically load required Grunt tasks
require('jit-grunt')(grunt, {
useminPrepare: 'grunt-usemin',
ngtemplates: 'grunt-angular-templates',
cdnify: 'grunt-google-cdn'
});
grunt.initConfig({
......
})
}删除
grunt.loadNpmTasks('grunt-contrib-uglify');
将会自动加载了。- 在命令行通过
grunt uglify
就可以执行了 - 完整
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
26module.exports = function(grunt) {
// 自动加载grunt模块
require('jit-grunt')(grunt, {
useminPrepare: 'grunt-usemin',
ngtemplates: 'grunt-angular-templates',
cdnify: 'grunt-google-cdn'
});
// 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'
}
}
});
// Load the plugin that provides the "uglify" task.
// grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};
grunt default(注册默认任务)
1 | // Default task(s). |
可以通过grunt uglify
或者grunt default
或者直接grunt
就可以启动和执行uglify
task,并且可以在数组里面,添加任意多个 task。
custom tasks
如果你需要的 tasks 不是通过 Grunt Plugins 定义的,那么你可以定义你自己的 tasks,
方式一、代码定义在 Gruntfile 中
1
2
3
4
5
6
7
8module.exports = function(grunt) {
// A very basic default task.
grunt.registerTask('default', 'Log some stuff.', function() {
grunt.log.write('Logging some stuff...').ok();
});
};方式二、可以将 function 以外部
.js
的方式定义在外部,并通过grunt.loadTasks进行加载
TODO, 未验证。