每当运行Grunt时, 你可以为其指定一个或多个任务, 这些任务用于告诉Grunt你想要它做什么事情。

如果你没有指定一个任务,并且你已经定义一个名为 "default" 的任务,那么该任务将会默认被执行。

任务别名

如果指定了一个任务列表taskList,新任务名taskName将是这一个或多个指定任务的别名。当运行此 "任务别名" 时,在taskList 中指定的每个任务都会按照其出现的顺序依次执行。taskList参数必须是一个任务数组。grunt.registerTask(taskName, taskList)

举个例子:

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

上面的任务别名案例中定义了一个 'default' 任务,如果运行Grunt时没有指定任何任务,它将自动执行'jshint'、'qunit'、'concat' 和 'uglify' 任务。

还可以给任务指定参数。在下面的例子中,别名 "dist" 将执行 "concat" 和 "uglify" 两个任务,并且它们都带有一个 "dist" 参数:

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

多任务

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

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

如果通过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并不会检查配置和环境 -- 它仅仅执行指定的任务函数,并传递任何使用冒号分割的参数作为函数的参数。举个例子:

  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. grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
  6. }
  7. });

如果执行 grunt foo:testing:123,将输出日志 foo, testing 123。 如果执行这个任务时不传递参数,只是执行 grunt foo,那么将输出日志 foo, no args

自定义任务

如果你的任务没有遵循 "多任务" 结构,那就可以使用自定义任务。比如:

  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. // Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
  3. grunt.task.run('bar', 'baz');
  4. // Or:
  5. grunt.task.run(['bar', 'baz']);
  6. });

任务也可以是异步的。比如:

  1. grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
  2. // Force task into async mode and grab a handle to the "done" function.
  3. var done = this.async();
  4. // Run some sync stuff.
  5. grunt.log.writeln('Processing task...');
  6. // And some async stuff.
  7. setTimeout(function() {
  8. grunt.log.writeln('All done!');
  9. done();
  10. }, 1000);
  11. });

任务也可以访问它们自身名称和参数。比如:

  1. grunt.registerTask('foo', 'My "foo" task.', function(a, b) {
  2. grunt.log.writeln(this.name, a, b);
  3. });
  4.  
  5. // 用法:
  6. // grunt foo
  7. // logs: "foo", undefined, undefined
  8. // grunt foo:bar
  9. // logs: "foo", "bar", undefined
  10. // grunt foo:bar:baz
  11. // logs: "foo", "bar", "baz"

如果任务在执行时记录到任何错误,那么任务就会失败。当任务失败时,所有的后续任务都将终止。比如:

  1. grunt.registerTask('foo', 'My "foo" task.', function() {
  2. return false;
  3. });
  4.  
  5. grunt.registerTask('bar', 'My "bar" task.', function() {
  6. // 如果"foo"任务运行失败或者没有运行则任务失败。
  7. grunt.task.requires('foo');
  8. // 如果"foo"任务运行成功则执行这里的代码。
  9. grunt.log.writeln('Hello, world.');
  10. });
  11.  
  12. // 用法:
  13. // grunt foo bar
  14. // 没有输出,bar任务没有运行,因为"foo"失败,所以它后面的任务都将终止运行。
  15. // grunt bar
  16. // 没有输出,bar任务运行,但运动到一半就停止了,因为"foo"从未运行,所以foo任务失败,失败后,bar任务也就停止了,因此没有输出。

注意 grunt.task.requires 并不会真正的运行其他任务,它仅仅检查其它任务是否已经执行,并且没有失败。

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

  1. grunt.registerTask('foo', 'My "foo" task.', function() {
  2. // 记录属性值,如果属性未定义(undefined)则返回null。
  3. grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name'));
  4. // 同样的记录属性值,如果属性未定义(undefined)则返回null。
  5. grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name']));
  6. });

如果任务需要的配置属性不存在,其也会失败。比如:

  1. grunt.registerTask('foo', 'My "foo" task.', function() {
  2. // 如果缺少"meta.name"配置属性则任务失败。
  3. grunt.config.requires('meta.name');
  4. // 如果缺少"mata.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. });

为什么我的异步task没有完成?
如果发生这种情况,可能是由于你忘记调用 this.async 方法来告诉Grunt你的任务是异步的。为了简单起见,Grunt使用同步的编码风格,可以在task体中通过调用 this.async() 将其转换为异步的。

注意,传递 false 给 done() 函数就会告诉Grunt你的任务已经失败。

例如:

  1. grunt.registerTask('asyncme', 'My asynchronous task.', function() {
  2. var done = this.async();
  3. setTimeout(function() {
        done(false); //代表asyncme任务失败
     }, 1000);
  4. });

加油!

grunt入门讲解4:如何创建task(任务)的更多相关文章

  1. grunt入门讲解5:创建插件,安装Grunt以及常见问题

    创建插件 创建插件主要有以下几个步骤: (1)通过 npm install -g grunt-init 命令安装 grunt-init .(2)通过 git clone git://github.co ...

  2. grunt入门讲解3:实例讲解使用 Gruntfile 配置任务

    这个Gruntfile 实例使用到了5个 Grunt 插件: grunt-contrib-uglify      grunt-contrib-qunitgrunt-contrib-concatgrun ...

  3. grunt入门讲解1:grunt的基本概念和使用

    Grunt和 Grunt 插件是通过 npm 安装并管理的,npm是 Node.js 的包管理器. Grunt 0.4.x 必须配合Node.js >= 0.8.0版本使用.老版本的 Node. ...

  4. grunt入门讲解2:如何使用 Gruntfile 配置任务

    Grunt的task配置都是在 Gruntfile 中的grunt.initConfig方法中指定的.此配置主要包括以任务名称命名的属性,和其他任意数据.一旦这些代表任意数据的属性与任务所需要的属性相 ...

  5. grunt入门讲解6:grunt使用步骤和总结

    Grunt是啥? 很火的前端自动化小工具,基于任务的命令行构建工具. Grunt能帮我们干啥? 假设有这样一个场景: 编码完成后,你需要做以下工作 HTML去掉注析.换行符 - HtmlMin CSS ...

  6. grunt入门讲解7:项目脚手架grunt-init

    grunt-init是一个用于自动创建项目脚手架的工具.它会基于当前工作环境和你给出的一些配置选项构建一个完整的目录结构.至于其所生成的具体文件和内容,依赖于你所选择的模版和构建过程中你对具体信息所给 ...

  7. Gradle学习系列之二——创建Task的多种方法

    在本系列的上篇文章中,我们讲到了Gradle入门,在本篇文章中我们将讲到创建Task的多种方法. 请通过以下方式下载本系列文章的Github示例代码: git clone https://github ...

  8. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...

  9. Mysql C语言API编程入门讲解

    原文:Mysql C语言API编程入门讲解 软件开发中我们经常要访问数据库,存取数据,之前已经有网友提出让鸡啄米讲讲数据库编程的知识,本文就详细讲解如何使用Mysql的C语言API进行数据库编程.   ...

随机推荐

  1. Gitlab+Jenkins学习之路(一)之Git基础

    1.GIT基础    GIT是一个分布式版本管理系统,速度快,适合大规模,跨地区多人协同开.SVN是一个集中式版本管理系统. (1)GIT生态 GIT分布式版本管理系统 Gitlab git私库解决方 ...

  2. SpringCloud-微服务的注册与发现Eureka(二)

    一.SpringCloud简介 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均 ...

  3. linux提权 searchsploit 使用规范

    使用 searchsploit 时,要把整个控制台最大化,这样才能显示完整的漏洞信息. 查看漏洞帮助文件:

  4. Python之函数的递归、匿名函数、内置函数

    一.函数的递归 ''' 1 什么是函数递归 函数递归调用(是一种特殊的嵌套调用):在调用一个函数的过程中,又直接或间接地调用了该函数本身 递归必须要有两个明确的阶段: 递推:一层一层递归调用下去,强调 ...

  5. Package设计1:选择数据类型、暂存数据和并发

    SSIS 设计系列: Package设计1:选择数据类型.暂存数据和并发 Package设计2:增量更新 Package 设计3:数据源的提取和使用暂存 一,数据类型的选择 对于SSIS的数据类型,容 ...

  6. virtualBox linux操作系统centos 挂载光盘

    virtualBox虚拟机linux centos 挂载光盘 第一步: 放入光盘 第二步: 挂载光驱 (/dev/cdrom) 1) 创建挂载点 mkdir /mnt/media 2) 挂载 moun ...

  7. 1.21 贪心入门上午PAT例题题解

    1.B1023 #include<cstdio> int a[10]; int main() { for(int i=0;i<=9;i++) { scanf("%d&quo ...

  8. JS对象,获取key和value

    var peopleArray=[] var peopleobj={jiangyx: "姜艳霞", yeluosen: "叶落森"} for(let i in ...

  9. 打包应用和构建Docker镜像(docker在windows上)

    在构建Docker时编译应用 一般有两种方法在构建镜像时进行打包应用.第一种方法就是使用基本的镜像,该镜像包括应用平台和构建工具,因此在Dockerfile中,复制源代码到镜像中并在构建镜像时编译ap ...

  10. Django_分页

    目录 基本语法 示例 示例1 使用django内置Paginator模块 示例2 改写Paginator 示例3 自定义pager组件 示例3.1 objs与pager各自单独使用 示例3.2 obj ...