Grunt 入门教程四:创建任务

任务是你在grunt中最常用到的,比如 jshint 和 nodeunit。每当grunt运行时,你都会定义一个或多个任务,通过这些任务告诉grunt你想做的事情。

重命名任务

如果有一个已经定义好的任务列表,那么可以创建一个新的任务作为一个或多个其他任务的别名。任何时候这个“别名任务”被运行,在这个“别名任务”中列出的任务都会按顺序执行。其中的 taskList 参数可以是一个任务数组。

grunt.registerTask(taskName, [description, ] taskList)

下面这个例子定义了一个default任务,当这个任务被执行时,会自动运行jshint、qunit、concat和uglify而不需要额外指定这个任务名字。

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

当然,定义任务的时候也可以指定参数(详见第二章)。比如下面这个例子:

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

多任务

(或者我觉得翻译成“复合任务”比较好,意思就是定义了多个目标的任务)

当一个多任务被运行时,grunt会在配置中找相同名字的属性。多任务可以有多个配置,每一个配置都是一个可以任意命名的“目标”。

通过 grunt concat:foo 或者 grunt concat:bar 这样的属性可以同时指定任务和目标,只运行concat任务中的foo或者bar目标。如果直接运行grunt concat而不指定目标的话,就会顺序执行concat下所有的目标。

如果一个任务被重命名了,grunt会去找config对象下的新名字。

大部分的contrib任务,包括 grunt-contrib-jshint(https://github.com/gruntjs/grunt-contrib-jshint),grunt-contrib-concat(https://github.com/gruntjs/grunt-contrib-concat)等都是多任务。

grunt.registerMultiTask(taskName, [description, ] taskFunction)

比如下面这个例子。如果运行 grunt log:foo,会输出  foo:1,2,3;如果运行 grunt log:bar 会输出 bar: 'hello world'。如果直接运行 grunt log, 会依次输出 foo: 1,2,3, bar:hello world和bas: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会输出"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 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.');
  }

  // Fail by returning false if this task had errors
  if (ifErrors) { return false; }

  grunt.log.writeln('This is the success message');
});

默认如果有一个任务失败,所有后续的任务都会失败(比如你执行jshint失败后就不用在执行uglifyjs),除非使用了--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.
// 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.
  grunt.config.requires('meta.name');
  // Also fails if "meta.name" config prop is missing.
  grunt.config.requires(['meta', 'name']);
  // Log... conditionally.
  grunt.log.writeln('This will only log if meta.name is defined in the config.');
});

任务可以直接访问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']));
});

更多例子参见 https://github.com/gruntjs/

为什么我的异步任务没有完成?

如果你没有使用 this.async() 来告诉grunt你的任务是异步的,那么就可能会发生这种错误。为了简单起见,grunt 使用了异步编码风格,通过在任务内调用 this.async()来告诉grunt这是一个异步任务。

注意,向done函数传递false表示任务失败。

grunt.registerTask('asyncme', 'My asynchronous task.', function() {
  var done = this.async();
  doSomethingAsync(done);
});
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值