任務是Grunt的面包和奶油考蕾。就像你常用的工具祸憋,如: jshint
或 nodeunit
。每當運行Grunt時, 你可以為其指定一個或多個任務, 這些任務用于告訴Grunt你想要它做什么事情肖卧。
如果你沒有指定一個任務蚯窥,并且你已經(jīng)定義一個名為 "default"
的任務,那么該任務將會默認被執(zhí)行(不用詫異塞帐,總要做點兒什么袄乖!)葵姥。
任務別名
如果指定了一個任務列表荷鼠,新任務將是這一個或多個指定任務的別名。當運行此 "任務別名" 時榔幸,在 taskList
中指定的每個任務都會按照其出現(xiàn)的順序依次執(zhí)行允乐。taskList
參數(shù)必須時一個任務數(shù)組。
grunt.registerTask(taskName, [description, ] taskList)
下面的任務別名案例中定義了一個 'default' 任務削咆,如果運行Grunt時沒有指定任何任務牍疏,它將自動執(zhí)行'jshint'、'qunit'拨齐、'concat' 和 'uglify' 任務鳞陨。
grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
還可以給任務指定參數(shù)。在下面的案例中奏黑,別名 "dist" 將執(zhí)行 "concat" 和 "uglify" 兩個任務炊邦,并且它們都帶有一個 "dist" 參數(shù):
grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);
多任務
當運行一個多任務時,Grunt會自動從項目的配置對象中查找同名屬性熟史。多任務可以有多個配置馁害,并且可以使用任意命名的'targets'。
同時指定像grunt concat:foo
或者grunt concat:bar
這樣的任務和目標蹂匹,在運行時Grunt只會處理指定目標的配置碘菜;然而如果運行grunt concat
,將會遍歷所有的目標, 并按任務指定的順序處理每個目標。注意忍啸,如果一個任務已經(jīng)使用grunt.task.renameTask重命名過仰坦,Grunt將會自動在配置對象中查找新任務名稱屬性。
大部分的contrib任務(主要是指官方提供的任務)计雌,包括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 log
運行Grunt, 它會輸出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);
});
"基本" 任務
當一個基本任務執(zhí)行時,Grunt并不會檢查配置和環(huán)境 -- 它僅僅執(zhí)行指定的任務函數(shù)罢缸,并傳遞任何使用冒號分割的參數(shù)作為函數(shù)的參數(shù)
grunt.registerTask(taskName, [description, ] taskFunction)
下面的案例中篙贸,如果執(zhí)行grunt foo:testing:123
,將輸出日志foo, testing 123
祖能。 如果執(zhí)行這個任務時不傳遞參數(shù)歉秫,只是執(zhí)行 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);
}
});
自定義任務
你可以和任務一起瘋狂雁芙。如果你的任務并沒有遵循 "多任務" 結(jié)構(gòu),那就使用自定義任務钞螟。
grunt.registerTask('default', 'My "default" task description.', function() {
grunt.log.writeln('Currently running the "default" task.');
});
在一個任務內(nèi)部兔甘,你可以執(zhí)行其他的任務。
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);
});
任務也可以訪問它們自身名稱和參數(shù)洞焙。
grunt.registerTask('foo', 'My "foo" task.', function(a, b) {
grunt.log.writeln(this.name, a, b);
});
// 用法:
// grunt foo foo:bar
// logs: "foo", undefined, undefined
// 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.');
}
// 如果這個任務出現(xiàn)錯誤則返回false
if (ifErrors) { return false; }
grunt.log.writeln('This is the success message');
});
當任務失敗時澡匪,所有后續(xù)任務都將終止,除非指定--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);
});
任務還可以依賴于其他任務的成功執(zhí)行唁情。注意grunt.task.requires
并不會真正的運行其他任務,它僅僅檢查其它任務是否已經(jīng)執(zhí)行甫匹,并且沒有失敗甸鸟。
grunt.registerTask('foo', 'My "foo" task.', function() {
return false;
});
grunt.registerTask('bar', 'My "bar" task.', function() {
// 如果"foo"任務運行失敗或者沒有運行則任務失敗惦费。
grunt.task.requires('foo');
// 如果"foo"任務運行成功則執(zhí)行這里的代碼。
grunt.log.writeln('Hello, world.');
});
// 用法:
// grunt foo bar
// 沒有輸出抢韭,因為"foo"失敗薪贫。
// grunt bar
// 沒有輸出,因為"foo"從未運行刻恭。
如果任務需要的配置屬性不存在瞧省,其也可能失敗。
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() {
// 記錄屬性值臀突,如果屬性未定義(undefined)則返回null。
grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name'));
// 同樣的記錄屬性值贾漏,如果屬性未定義(undefined)則返回null。
grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name']));
});
在 contrib tasks 中可以查看更多案例藕筋。