创建任务

    如果你没有指定任务,但是定义了一个名为”default”的任务,那么该任务(default任务)将默认运行(不要惊讶,顾名思义它代表默认会运行哪些定义好的任务)。

    如果指定了一个任务列表,新任务(名)便是其他一个或多个任务的别名。每当运行’别名任务’时,指定在taskList中的每个任务(指在grunt.initConfig()中定义的任务)都会按照指定它们的顺序运行。taskList参数必须是一个任务数组。其语法如下:

    这里有一个例子,它定义了一个名为’default’别名任务,如果运行Grunt时没有指定任何任务,它将自动运行’jshint’,’qunit’,’concat’和’uglify’任务。

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

    可以给任务指定参数。在下面的例子中,别名任务’dist’会运行’concat’和’uglify’这两个任务,并且每个任务都带有一个’dist’参数:

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

    多任务

    当运行一个多任务时,Grunt会自动从项目的配置对象中查找同名属性。多任务可以有多个配置,并且可以使用任意命名的’targets’。

    同时指定像grunt concat:foo或者grunt concat:bar这样的任务和目标,在运行时Grunt只会处理指定目标的配置;然而如果运行grunt concat,将会遍历所有的目标, 并按任务指定的顺序处理每个目标。注意,如果一个任务已经使用重命名过,Grunt将会自动在配置对象中查找新任务名称属性。

    大部分的contrib任务(主要是指官方提供的任务),包括grunt-contrib-jshint插件的jshint任务,以及都是多任务形式的。

    1. grunt.registerMultiTask(taskName, [description, ] taskFunction);
    1. grunt.initConfig({
    2. log: {
    3. foo: [1,2,3],
    4. bar: 'hello world',
    5. baz: false
    6. }
    7. });
    8. grunt.registerTask('log','log stuff.', function(){
    9. grunt.log.writeln(this.target + ': ' + this.data);
    10. });

    当运行一个基本任务时,Grunt并不会查找配置和检查运行环境—它仅仅运行指定的任务函数,可以传递任意使用冒号分割的参数作为任务函数的参数(注意多任务中的冒号并不是传递参数,而是指定具体任务的目标)。

    这里有一个例子演示了如果通过grunt foo123运行Grunt将输出foo, testing 123。如果运行这个任务时不传递参数,只运行grunt foo,那么这个任务会输出foo, no args

    1. grunt.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) {
    2. if (arguments.length === 0) {
    3. grunt.log.writeln(this.name + ", no args");
    4. } else {
    5. }
    6. });

    自定义任务

    你可能会着迷于任务。但是如果你的任务并没有遵循多任务结构,那么你可以使用自定义任务。

    1. grunt.registerTask('default', 'My "default" task description.', function(){
    2. grunt.log.writeln('Currently running the "default" task.');
    3. });

    在任务的内部,你还可以运行其他的任务。

    1. grunt.registerTask('foo', 'My "foo" task.', function() {
    2. grunt.task.run('bar', 'baz');
    3. // Or:
    4. grunt.task.run(['bar', 'baz']);
    5. });

    任务还可以是异步的.

    1. grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
    2. //将任务转变为异步模式并交给done函数处理
    3. var done = this.async();
    4. //同步任务
    5. grunt.log.writeln('Processing task...');
    6. //异步任务
    7. setTimeout(function() {
    8. grunt.log.writeln('All done!');
    9. done();
    10. }, 1000);
    11. });

    任务也可以访问它们自身名称和参数.

    如果任务记录到错误信息,还可以终止任务执行(通过标记任务失败的方式)。

    1. grunt.registerTask('foo', 'My "foo" task.', function() {
    2. if (failureOfSomeKind) {
    3. grunt.log.error('This is an error message.');
    4. }
    5. //如果这个任务抛出错误则返回false
    6. if (ifErrors) { return false; }
    7. grunt.log.writeln('This is the success message');
    8. });
    1. grunt.registerTask('foo', 'My "foo" task.', function() {
    2. // Fail synchronously.
    3. return false;
    4. });
    5. grunt.registerTask('bar', 'My "bar" task.', function() {
    6. setTimeout(function() {
    7. // Fail asynchronously
    8. done(false);
    9. }, 1000);
    10. });

    任务还可以依赖于其他任务的成功执行。注意grunt.task.requires并不会运行其他任务(比如参数中指定的任务)。它仅仅检查那些任务(其他任务)的运行并没有失败(即其他任务,也就是所依赖的任务是否失败)。

    1. grunt.registerTask('foo', 'My "foo" task.', function() {
    2. return false;
    3. });
    4. grunt.registerTask('bar', 'My "bar" task.', function() {
    5. //如果foo任务运行失败或者没有运行则任务失败
    6. grunt.task.requires('foo');
    7. //如果foo任务运行成功则执行这里的代码
    8. grunt.log.writeln('Hello, world.');
    9. });
    10. // 用法
    11. // grunt foo bar
    12. // 没有输出,因为foo失败
    13. // grunt bar
    14. // 没有输出,因为foo从未运行

    如果任务需要的配置属性不存在,任务也可能失败。

    1. grunt.registerTask('foo', 'My "foo" task', function(){
    2. //如果缺省"meta.name"配置属性则任务失败
    3. grunt.config.requires('meta.name');
    4. //与上一句相同,如果缺省"meta.name"配置属性则任务失败
    5. grunt.config.requires(['meta', 'name']);
    6. //附加记录
    7. grunt.log.writeln('This will only log if meta.name is defined in the config');
    8. });

    任务还可以访问配置属性。

    在中可以查看更多的例子。

    TODO(从FAQ拉取,推荐process.env)

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

    可能由于你忘记调用方法来告诉Grunt你的任务是异步的,那么就可能会发生这种情况(异步任务失败)。为了简单起见,Grunt使用同步的编码风格,可以在任务体中通过调用this.async将该任务(调用这个方法的任务)转换为异步的。

    注意传递falsedone函数就会告诉Grunt任务已经失败。

    1. grunt.registerTask('asyncme', 'My asynchronous task.', function(){
    2. var done = this.async();
    3. });