您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Grunt 配置任务

Grunt配置

Grunt的task配置都是在 Gruntfile 中的grunt.initCon中指定的。此配置主要是以任务命名的,也可以包含其他任意数据。一旦这些代表任意数据的与任务所需要的相冲突,就将被忽略。

此外,由于这本身就是JavaScript,因此你不仅限于使用JSON;你可以使用任何有效的JavaScript。必要的情况下,你甚至可以以编程的方式配置。

grunt.initCon({
  concat: {
    // 这里是concat任务的配置信息。
  },
  uglify: {
    // 这里是uglify任务的配置信息
  },
  // 任意数据。
  my_property: 'whatever',
  my_src_files: ['foo/*.js', 'bar/*.js'],
});

任务配置和目标

当运行任务时,Grunt会查找配置对象中的同名。多任务(multi-task)可以通过任意命名的“目标(target)”来定义多个配置。在下面的案例中,concat任务有名为foo和bar两个目标,而uglify任务仅仅只有名为bar目标。

grunt.initCon({
  concat: {
    foo: {
      // concat task "foo" target options and files go here.
    },
    bar: {
      // concat task "bar" target options and files go here.
    },
  },
  uglify: {
    bar: {
      // uglify task "bar" target options and files go here.
    },
  },
});

同时指定任务(task)和目标(target),例如grunt concat:foo或者grunt concat:bar,将只会处理指定目标(target)的配置,而运行grunt concat将遍历所有目标(target)并依次处理。注意,如果任务使用过,Grunt将在配置对象中查找以新的任务名命名的。

options

在任务配置中,options可以用来指定覆盖内置的认值。此外,每目标(target)中还可以拥有专门针对此目标(target)的options。目标(target)级的平options将会覆盖任务级的options。

options对象是可选的,如果不需要,可以忽略。

grunt.initCon({
  concat: {
    options: {
      // 这里是任务级的Options,覆盖认值 
    },
    foo: {
      options: {
        // "foo" target options may go here, overriding task-level options.
      },
    },
    bar: {
      // No options specified; this target will use task-level options.
    },
  },
});

由于大多的任务都是执行操作,Grunt有强大的抽象层用于声明任务应该操作哪些。这里有好几种定义src-dest(源-目标)映射的方式,均提供了不同程度的描述和控制操作方式。任何一种多任务(multi-task)都能理解下面的格式,所以你只需要选择满足你需求的格式就行。

所有的格式都src和dest,此外"Compact"[简洁]和"Files Array"[数组]格式还以下一些额外的:

filter 它通过接受任意有效的或者来匹配src路径并根据匹配结果返回true或者false。

nonull 如果被设置为 true,未匹配的模式也将执行。结合Grunt的--verbore标志, 这个选项可以帮助用来调试路径的问题。

dot 它允许模式模式匹配句点开头的名,即使模式并不明确名开头部分是否有句点。

matchBase如果设置这个,缺少斜线的模式(意味着模式中不能使用斜线进行路径的匹配)将不会匹配包含在斜线中的名。 例如,a?b将匹配/xyz/123/acb但不匹配/xyz/acb/123。

expand 处理动态的src-dest映射。

其他的将作为匹配项传递给底层的库。 请查看 和 文档以更多信息。

简洁格式

这种形式允许每个目标对应src-dest映射。通常情况下它用于只读任务,比如,它就只需要单一的src,而不需要关联的dest选项. 这种格式还支给每个src-dest映射指定额外的。

grunt.initCon({
  jshint: {
    foo: {
      src: ['src/aa.js', 'src/aaa.js']
    },
  },
  concat: {
    bar: {
      src: ['src/bb.js', 'src/bbb.js'],
      dest: 'dest/b.js',
    },
  },
});

对象格式

这种形式每个目标对应多个src-dest形式的映射,名就是目标,源就是它的值(源列表则使用声明)。可以使用这种方式指定数个src-dest映射, 但是不能够给每个映射指定附加的。

grunt.initCon({
  concat: {
    foo: {
      files: {
        'dest/a.js': ['src/aa.js', 'src/aaa.js'],
        'dest/a1.js': ['src/aa1.js', 'src/aaa1.js'],
      },
    },
    bar: {
      files: {
        'dest/b.js': ['src/bb.js', 'src/bbb.js'],
        'dest/b1.js': ['src/bb1.js', 'src/bbb1.js'],
      },
    },
  },
});

这种形式每个目标对应多个src-dest映射,同时也允许每个映射拥有额外:

grunt.initCon({
  concat: {
    foo: {
      files: [
        {src: ['src/aa.js', 'src/aaa.js'], dest: 'dest/a.js'},
        {src: ['src/aa1.js', 'src/aaa1.js'], dest: 'dest/a1.js'},
      ],
    },
    bar: {
      files: [
        {src: ['src/bb.js', 'src/bbb.js'], dest: 'dest/b/', nonull: true},
        {src: ['src/bb1.js', 'src/bbb1.js'], dest: 'dest/b1/', filter: 'isFile'},
      ],
    },
  },
});

较老的格式

dest-as-target格式在多任务和目标出现之前是过渡形式,目标路径实际上就是目标。遗憾的是, 由于目标是路径,那么运行grunt task:target可能不合适。此外,你也不能指定目标级的options或者给每个src-dest映射指定额外。

此种格式已经不赞成使用,请尽量不要使用。

grunt.initCon({
  concat: {
    'dest/a.js': ['src/aa.js', 'src/aaa.js'],
    'dest/b.js': ['src/bb.js', 'src/bbb.js'],
  },
});

过滤

filter可以给你的目标提供更高级的详细帮助信息。只需要使用有效的。下面的配置仅仅清理与模式匹配的真实的:

grunt.initCon({
  clean: {
    foo: {
      src: ['tmp/**/*'],
      filter: 'isFile',
    },
  },
});

或者创建你自己的filter,根据是否匹配来返回true或者false。下面的例子将仅仅清理空目录:

grunt.initCon({
  clean: {
    foo: {
      src: ['tmp/**/*'],
      filter: function(filepath) {
        return (grunt.file.isDir(filepath) && require('fs').readdirSync(filepath).length === 0);
      },
    },
  },
});

符模式

通常分别指定所有源路径是不切实际的,因此Grunt通过内置 和  库来匹配名(又叫作globbing)。

然这并不是综合的匹配模式方面的教程,你只需要知道如何在路径匹配过程中使用它们即可:

* 匹配任意的字符,但不匹配 /

? 匹配单个字符,但不匹配 /

** 匹配任意的字符, /,只要它是路径中唯一的一部分

{} 允许使用逗号分割的“或”表达式列表

! 在模式的开头用于排除匹配模式所匹配的任何

每个人都需要知道的是:foo/*.js将匹配位于foo/目录下的所有的.js结尾的;而foo/**/*js将匹配foo/目录以及其子目录中所有以.js结尾的。

此外, 为了简化原本复杂的符模式,Grunt允许指定数组形式的路径或者符模式。所有模式按顺序处理,模式处理的过程中,带有!前缀的模式所匹配的将不包含在结果集中。 而且其结果集中的每一项也是唯一的。

例如:

// 指定单个:
{src: 'foo/this.js', dest: ...}
// 指定数组:
{src: ['foo/this.js', 'foo/that.js', 'foo/the-other.js'], dest: ...}
// 使用匹配模式:
{src: 'foo/th*.js', dest: ...}

// 独立的node-glob模式:
{src: 'foo/{a,b}*.js', dest: ...}
// 也可以这样编写:
{src: ['foo/a*.js', 'foo/b*.js'], dest: ...}

// foo目录中所有的.js,按字母顺序排序:
{src: ['foo/*.js'], dest: ...}
// 首先是bar.js,接着是剩下的.js,并按字母顺序排序:
{src: ['foo/bar.js', 'foo/*.js'], dest: ...}

// 除bar.js之外的所有的.js,按字母顺序排序:
{src: ['foo/*.js', '!foo/bar.js'], dest: ...}
// 按字母顺序排序的所有.js,但是bar.js在最后。
{src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: ...}

// 模板也可以用于路径或者匹配模式中:
{src: ['src/<%= basename %>.js'], dest: 'build/<%= basename %>.min.js'}
// 它们也可以引用在配置中定义的其他列表:
{src: ['foo/*.js', '<%= jshint.all.src %>'], dest: ...}

更多关于符模式的语法,请查看 和  的文档。

动态构建对象

当你希望处理大量的单个时,这里有一些附加的可以用来动态的构建列表。这些都可以用于Compact和Files Array映射格式。

expand 设置为true用于启用下面的选项:

cwd 所有src指定的匹配都将相对于此处指定的路径(但不此路径) 。

src 相对于cwd路径的匹配模式。

dest 目标路径前缀。

ext 对于的dest路径中所有实际存在,均使用这个值替换扩展名。

extDot 用于指定扩展名的英文点号的所在位置。可以赋值 'first' (扩展名从名中的第英文点号开始) 或 'last' (扩展名从最后英文点号开始),认值为 'first' [于 0.4.3 版本]

flatten 从的dest路径中移除所有的路径部分。

rename 对每个匹配的src这个(在后缀和移除路径之后)。dest和匹配的src路径将被作为参数传入,此应该返回新的dest值。 如果相同的dest返回不止一次,那么,每个返回此值的src来源都将被到数组中作为源列表。

在下面的例子中,uglify 任务中的static_mappings和dynamic_mappings两个目标具有相同的src-dest映射列表, 这是因为任务运行时Grunt会展开dynamic_mappings对象为4个单独的静态src-dest映射--假设这4个能够找到。

可以指定任意静态src-dest和动态的src-dest映射相互结合。

grunt.initCon({
  uglify: {
    static_mappings: {
      // Because these src-dest file mappings are manually specified, every
      // time a new file is added or removed, the Gruntfile has to be updated.
      files: [
        {src: 'lib/a.js', dest: 'build/a.min.js'},
        {src: 'lib/b.js', dest: 'build/b.min.js'},
        {src: 'lib/subdir/c.js', dest: 'build/subdir/c.min.js'},
        {src: 'lib/subdir/d.js', dest: 'build/subdir/d.min.js'},
      ],
    },
    dynamic_mappings: {
      // Grunt will search for "**/*.js" under "lib/" when the "uglify" task
      // runs and build the appropriate src-dest file mappings then, so you
      // don't need to update the Gruntfile when files are added or removed.
      files: [
        {
          expand: true,     // Enable dynamic expansion.
          cwd: 'lib/',      // Src matches are relative to this path.
          src: ['**/*.js'], // Actual pattern(s) to match.
          dest: 'build/',   // Destination path prefix.
          ext: '.min.js',   // Dest filepaths will have this extension.
          extDot: 'first'   // Extensions in filenames begin after the first dot
        },
      ],
    },
  },
});

模板

使用<% %>分隔符指定的模板会在任务从它们的配置中读取相应的数据时将扩展扫描。模板会被递归的展开,直到配置中不再存在遗留的模板相关的信息(与模板匹配的)。

整个配置对象决定了上下文(模板中的)。此外,在模板中使用grunt以及它的都是有效的,例如: <%= grunt.template.today('yyyy-mm-dd') %>。

<%= prop.subprop %> 将会展开配置信息中的prop.subprop的值,不管是什么类型。像这样的模板不仅可以用来引用字符串值,还可以引用数组或者其他对象类型的值。

<% %> 执行任意内联的JavaScript。对于控制流或者循环来说是非常有用的。

下面以concat任务配置为例,运行grunt concat:sample时将通过banner中的/* abcde */连同foo/*.js+bar/*.js+bar/*.js匹配的所有来名为build/abcde.js的。

grunt.initCon({
  concat: {
    sample: {
      options: {
        banner: '/* <%= baz %> */\n',   // '/* abcde */\n'
      },
      src: ['<%= qux %>', 'baz/*.js'],  // [['foo/*.js', 'bar/*.js'], 'baz/*.js']
      dest: 'build/<%= baz %>.js',      // 'build/abcde.js'
    },
  },
  //用于任务配置模板的任意
  foo: 'c',
  bar: 'b<%= foo %>d', // 'bcd'
  baz: 'a<%= bar %>e', // 'abcde'
  qux: ['foo/*.js', 'bar/*.js'],
});

导入外部数据

在下面的Gruntfile中,项目的元数据是从package.json中导入到Grunt配置中的,并且中的 uglify 任务被配置用于压缩源以及使用该元数据动态的banner注释。

Grunt有grunt.file.readJSON和grunt.file.readYAML两个分别用于引入JSON和YAML数据。

grunt.initCon({
  pkg: grunt.file.readJSON('package.json'),
  uglify: {
    options: {
      banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
    },
    dist: {
      src: 'src/<%= pkg.name %>.js',
      dest: 'dist/<%= pkg.name %>.min.js'
    }
  }
});

联系我
置顶