黑人生命也是命

建立工作

工作是 Grunt 的核心。您最常執行的內容,例如 jshintnodeunit。每次執行 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:foogrunt 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,3bar: hello worldbaz: 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 文件。