创建任务
任务是 Grunt 的核心。您最常做的事情,比如 jshint
或 nodeunit
。每次运行 Grunt 时,您都需要指定一个或多个要运行的任务,这告诉 Grunt 您希望它做什么。
如果您没有指定任务,但定义了一个名为“default”的任务,那么该任务将默认运行(不出所料)。
别名任务
如果指定了任务列表,则新任务将是一个或多个其他任务的别名。每当运行此“别名任务”时,taskList
中指定的每个任务都将按指定的顺序运行。 taskList
参数必须是任务数组。
grunt.registerTask(taskName, [description, ] taskList)
此示例别名任务定义了一个“default”任务,如果在不指定任何任务的情况下执行 Grunt,则将自动运行“jshint”、“qunit”、“concat”和“uglify”任务。
grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
也可以指定任务参数。在此示例中,别名“dist”运行“concat”和“uglify”任务,每个任务都有一个“dist”参数。
grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);
多任务
当运行多任务时,Grunt 会在 Grunt 配置中查找同名属性。多任务可以有多个配置,使用任意命名的“目标”定义。
同时指定任务和目标(如 grunt concat:foo
或 grunt concat:bar
)将仅处理指定目标的配置,而运行 grunt concat
将迭代*所有*目标,依次处理每个目标。请注意,如果使用 grunt.task.renameTask 重命名了任务,Grunt 将在配置对象中查找具有*新*任务名称的属性。
大多数贡献任务,包括 grunt-contrib-jshint 插件 jshint 任务 和 grunt-contrib-concat 插件 concat 任务 都是多任务。
grunt.registerMultiTask(taskName, [description, ] taskFunction)
给定指定的配置,如果通过 grunt log:foo
运行 Grunt,则此示例多任务将记录 foo: 1,2,3
,或者如果通过 grunt log:bar
运行 Grunt,则将记录 bar: hello world
。但是,如果 Grunt 作为 grunt log
运行,它将记录 foo: 1,2,3
,然后记录 bar: hello world
,然后记录 baz: false
。
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);
});
“基本”任务
当运行基本任务时,Grunt 不会查看配置或环境,它只运行指定的 task 函数,将任何指定的以冒号分隔的参数作为函数参数传入。
grunt.registerTask(taskName, [description, ] taskFunction)
如果通过 grunt foo:testing:123
运行 Grunt,则此示例任务将记录 foo, testing 123
。如果在没有参数的情况下以 grunt foo
的形式运行任务,则该任务将记录 foo, no args
。
grunt.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) {
if (arguments.length === 0) {
grunt.log.writeln(this.name + ", no args");
} else {
grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
}
});
自定义任务
您可以随意使用任务。如果您的任务不遵循“多任务”结构,请使用自定义任务。
grunt.registerTask('default', 'My "default" task description.', function() {
grunt.log.writeln('Currently running the "default" task.');
});
在任务内部,您可以运行其他任务。
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']);
});
任务可以是异步的。
grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
// Force task into async mode and grab a handle to the "done" function.
var done = this.async();
// Run some sync stuff.
grunt.log.writeln('Processing task...');
// And some async stuff.
setTimeout(function() {
grunt.log.writeln('All done!');
done();
}, 1000);
});
任务可以访问自己的名称和参数。
grunt.registerTask('foo', 'My "foo" task.', function(a, b) {
grunt.log.writeln(this.name, a, b);
});
// Usage:
// grunt foo
// logs: "foo", undefined, undefined
// grunt foo:bar
// logs: "foo", "bar", undefined
// grunt foo:bar:baz
// logs: "foo", "bar", "baz"
如果记录了任何错误,则任务可能会失败。
grunt.registerTask('foo', 'My "foo" task.', function() {
if (failureOfSomeKind) {
grunt.log.error('This is an error message.');
}
// Fail by returning false if this task had errors
if (ifErrors) { return false; }
grunt.log.writeln('This is the success message');
});
当任务失败时,所有后续任务都将中止,除非指定了 --force
。
grunt.registerTask('foo', 'My "foo" task.', function() {
// Fail synchronously.
return false;
});
grunt.registerTask('bar', 'My "bar" task.', function() {
var done = this.async();
setTimeout(function() {
// Fail asynchronously.
done(false);
}, 1000);
});
任务可能依赖于其他任务的成功执行。请注意,grunt.task.requires
实际上不会运行其他任务。它只会检查它是否已运行且未失败。
grunt.registerTask('foo', 'My "foo" task.', function() {
return false;
});
grunt.registerTask('bar', 'My "bar" task.', function() {
// Fail task if "foo" task failed or never ran.
grunt.task.requires('foo');
// This code executes if the "foo" task ran successfully.
grunt.log.writeln('Hello, world.');
});
// Usage:
// grunt foo bar
// doesn't log, because foo failed.
// ***Note: This is an example of space-separated sequential commands,
// (similar to executing two lines of code: `grunt foo` then `grunt bar`)
// grunt bar
// doesn't log, because foo never ran.
如果所需的配置属性不存在,则任务可能会失败。
grunt.registerTask('foo', 'My "foo" task.', function() {
// Fail task if "meta.name" config prop is missing
// Format 1: String
grunt.config.requires('meta.name');
// or Format 2: Array
grunt.config.requires(['meta', 'name']);
// Log... conditionally.
grunt.log.writeln('This will only log if meta.name is defined in the config.');
});
任务可以访问配置属性。
grunt.registerTask('foo', 'My "foo" task.', function() {
// Log the property value. Returns null if the property is undefined.
grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name'));
// Also logs the property value. Returns null if the property is undefined.
grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name']));
});
查看 贡献任务 以获取更多示例。
CLI 选项/环境
使用 process.env
访问 环境变量。
在 使用 CLI 页面上阅读有关可用命令行选项的更多信息。
为什么我的异步任务没有完成?
发生这种情况的原因可能是您忘记调用 this.async 方法来告诉 Grunt 您的任务是异步的。为了简单起见,Grunt 使用同步编码风格,可以通过在任务主体中调用 this.async()
切换到异步。
请注意,将 false
传递给 done()
函数会告诉 Grunt 任务已失败。
例如
grunt.registerTask('asyncme', 'My asynchronous task.', function() {
var done = this.async();
doSomethingAsync(done);
});
额外参考
如果您需要额外的参考来创建任务,请查看 API 文档。