grunt入門講解4:如何建立task(任務)

每當運行Grunt時, 你能夠爲其指定一個或多個任務, 這些任務用於告訴Grunt你想要它作什麼事情。數組

若是你沒有指定一個任務,而且你已經定義一個名爲 "default" 的任務,那麼該任務將會默認被執行。異步

任務別名

若是指定了一個任務列表taskList,新任務名taskName將是這一個或多個指定任務的別名。當運行此 "任務別名" 時,在taskList 中指定的每一個任務都會按照其出現的順序依次執行。taskList參數必須是一個任務數組。grunt.registerTask(taskName, taskList)async

舉個例子:函數

grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);grunt

上面的任務別名案例中定義了一個 'default' 任務,若是運行Grunt時沒有指定任何任務,它將自動執行'jshint'、'qunit'、'concat' 和 'uglify' 任務。ui

還能夠給任務指定參數。在下面的例子中,別名 "dist" 將執行 "concat" 和 "uglify" 兩個任務,而且它們都帶有一個 "dist" 參數:this

grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);編碼

多任務

當運行一個多任務時,Grunt會自動從項目的配置對象中查找同名屬性。多任務能夠有多個配置,而且可使用任意命名的'targets'。舉個例子:spa

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 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並不會檢查配置和環境 -- 它僅僅執行指定的任務函數,並傳遞任何使用冒號分割的參數做爲函數的參數。舉個例子:

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 foo:testing:123,將輸出日誌 foo, testing 123。 若是執行這個任務時不傳遞參數,只是執行 grunt foo,那麼將輸出日誌 foo, no args

自定義任務

若是你的任務沒有遵循 "多任務" 結構,那就可使用自定義任務。好比:

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);
});

// 用法:
// 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() {
  return false;
});

grunt.registerTask('bar', 'My "bar" task.', function() {
  // 若是"foo"任務運行失敗或者沒有運行則任務失敗。
  grunt.task.requires('foo');
  // 若是"foo"任務運行成功則執行這裏的代碼。
  grunt.log.writeln('Hello, world.');
});

// 用法:
// grunt foo bar
//   沒有輸出,bar任務沒有運行,由於"foo"失敗,因此它後面的任務都將終止運行。
// grunt bar
//   沒有輸出,bar任務運行,但運動到一半就中止了,由於"foo"從未運行,因此foo任務失敗,失敗後,bar任務也就中止了,所以沒有輸出。

注意 grunt.task.requires 並不會真正的運行其餘任務,它僅僅檢查其它任務是否已經執行,而且沒有失敗。

任務還能夠訪問配置屬性。好比:

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']));
});

若是任務須要的配置屬性不存在,其也會失敗。好比:

grunt.registerTask('foo', 'My "foo" task.', function() {
  // 若是缺乏"meta.name"配置屬性則任務失敗。
  grunt.config.requires('meta.name');
  // 若是缺乏"mata.name"配置屬性則任務一樣失敗。
  grunt.config.requires(['meta', 'name']);
  // 根據狀況記錄日誌。
  grunt.log.writeln('This will only log if meta.name is defined in the config.');
});

爲何個人異步task沒有完成?
若是發生這種狀況,多是因爲你忘記調用 this.async 方法來告訴Grunt你的任務是異步的。爲了簡單起見,Grunt使用同步的編碼風格,能夠在task體中經過調用 this.async() 將其轉換爲異步的。

注意,傳遞 false 給 done() 函數就會告訴Grunt你的任務已經失敗。

例如:

grunt.registerTask('asyncme', 'My asynchronous task.', function() {
  var done = this.async();
  setTimeout(function() { 
    done(false); //表明asyncme任務失敗
 }, 1000);
});

 

 

 

 

加油!

相關文章
相關標籤/搜索