安装grunt之前确保npm更新到最新的版本,使用npm update -g npm在命令行中进行升级
1,安装全局的grunt-cli
grunt-cli并不是grunt,cli用于加载grunt,并传递Gruntfile中的配置信息,然后按照Gruntfile中指定的任务运行grunt。Gruntfile可以理解为Ant中的build.xml文件,里面描述了grunt要运行哪些任务,如何运行等信息。Gruntfile是一个标准的js文件,通常放在项目根目录下。
安装命令:npm install -g grunt-cli
命令需要在管理员权限下执行,否则会报错。上述命令执行完后,grunt 命令就被加入到你的系统路径中了,以后就可以在任何目录下执行此命令了。
2,在项目根目录下新建package.json,Gruntfile.js文件
package.json文件可利用npm init命令创建一个最基本的文件。它主要描述了项目的名称,版本,依赖哪些grunt插件,以便将此项目发布为npm模块。grunt本身和grunt插件都需要进行安装,grunt用于整个项目的构建,grunt插件才是实现整个构建过程中每一步功能的模块,例如需要合并js文件,就需要找相应的grunt插件。
package.json示例
{
"name": "htmltest",
"version": "1.0.0",
"description": "test",
"main": "index.js",
"dependencies": {
"npm": "^2.15.1"
},
"devDependencies": {
"grunt": "^1.0.1",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-nodeunit": "^1.0.0",
"grunt-contrib-uglify": "^1.0.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "zhang",
"license": "ISC"
}
Gruntfile.js示例:
/**
* Created by Administrator on 16-4-26.
*/
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']);
};
这个文件描述了对名为pkg.name的js文件进行压缩的任务。在项目根目录运行grunt命令,就会压缩完成。
3,在Gruntfile.js文件目录下执行安装grunt和grunt插件命令,完成后会在同级目录创建node_modules目录来保存grunt本身和grunt插件。然后package.json中的devDependencies依赖描述会自动更新。
安装命令:npm install grunt --save-dev
npm install grunt-contrib-jshint --save-dev
安装完成后grunt和grunt插件是安装在项目下,并非全局的。在未安装grunt的目录下运行grunt命令会报错。
4,下面是一个完整的Gruntfile文件示例
module.exports = function(grunt) {
//grunt的所有任务和目标都配置在grunt.initConfig中
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'), //读取json文件,后面可以通过模块使用json文件中的对象了
concat: { //concat任务 连接文件为一个文件 可以通过grunt concat单独运行
options: { //任务级属性 可以用来指定覆盖内置属性的默认值 目标中也可以指定opitons且会覆盖任务级的
separator: ';'
},
dist: { //dist是任务中的目标,一个任务可有多个目标 可通过grunt concat:dist单独运行
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: { //uglify任务 压缩文件
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: { //将concat任务的dist目标的目的文件压缩
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
qunit: {
files: ['test/**/*.html']
},
jshint: {
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
options: {
//这里是覆盖JSHint默认配置的选项
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
watch: { //监控文件变化的任务
files: ['<%= jshint.files %>'],
tasks: ['jshint', 'qunit']
}
});
//加载已安装的任务模块
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
//注册任务test 运行grunt test会运行jshint qunit两个任务
grunt.registerTask('test', ['jshint', 'qunit']);
//注册一个默认的任务 只运行grunt会运行这个默认任务
grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
};
5,Grunt的任务
任务别名:grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);
指定任务别名为dist 会运行两个任务,[]为任务列表
多任务:
grunt.initConfig({
log: {
foo: [1, 2, 3],
bar: 'hello world',
baz: false
}
});
grunt.registerMultiTask('log', 'Log stuff.', function() {
grunt.log.writeln(this.target + ': ' + this.data);
});
自定义任务:自定义一个任务foo,执行任务函数,在里面先执行bar baz
grunt.registerTask('foo', 'My "foo" task.', function() {
// Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
grunt.task.run('bar', 'baz');
// Or:
grunt.task.run(['bar', 'baz']);
});