建立工作
工作是 Grunt 的核心。您最常執行的內容,例如 jshint
或 nodeunit
。每次執行 Grunt 時,您會指定一個或多個要執行的工作,告訴 Grunt 您希望它執行什麼動作。
如果您未指定工作,但已定義名稱為「預設」的工作,則該工作會(不出所料地)預設執行。
別名工作
如果指定工作清單,則新工作會成為一個或多個其他工作的別名。每當執行這個「別名工作」時,taskList
中指定的每個工作都會按指定順序執行。taskList
參數必須是工作陣列。
grunt.registerTask(taskName, [description, ] taskList)
這個範例別名工作定義一個「預設」工作,如果在未指定任何工作的情況下執行 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 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);
});
「基本」工作
當執行基本工作時,Grunt 不會查看組態或環境—它只會執行指定的任務函數,並將任何指定的冒號分隔引數傳遞為函數引數。
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']));
});
請查看 contrib 工作 以取得更多範例。
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 文件。