这个指南解释了如何使用 Gruntfile 来为你的项目配置task。如果你还不知道 Gruntfile 是什么,请先阅读 快速入门 指南并看看这个Gruntfile 实例

Grunt配置

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

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

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

任务配置和目标

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

grunt.initConfig({
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.task.renameTask重命名过,Grunt将在配置对象中查找以新的任务名命名的属性。

options属性

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

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

grunt.initConfig({
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)都能理解下面的格式,所以你只需要选择满足你需求的格式就行。

所有的文件格式都支持srcdest属性,此外"Compact"[简洁]和"Files Array"[文件数组]格式还支持以下一些额外的属性:

  • filter 它通过接受任意一个有效的fs.Stats方法名或者一个函数来匹配src文件路径并根据匹配结果返回true或者false
  • nonull 如果被设置为 true,未匹配的模式也将执行。结合Grunt的--verbore标志, 这个选项可以帮助用来调试文件路径的问题。
  • dot 它允许模式模式匹配句点开头的文件名,即使模式并不明确文件名开头部分是否有句点。
  • matchBase如果设置这个属性,缺少斜线的模式(意味着模式中不能使用斜线进行文件路径的匹配)将不会匹配包含在斜线中的文件名。 例如,a?b将匹配/xyz/123/acb但不匹配/xyz/acb/123
  • expand 处理动态的src-dest文件映射,更多的信息请查看动态构建文件对象
  • 其他的属性将作为匹配项传递给底层的库。 请查看node-glob 和minimatch 文档以获取更多信息。

简洁格式

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

grunt.initConfig({
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.initConfig({
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.initConfig({
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.initConfig({
concat: {
'dest/a.js': ['src/aa.js', 'src/aaa.js'],
'dest/b.js': ['src/bb.js', 'src/bbb.js'],
},
});

自定义过滤函数

filter属性可以给你的目标文件提供一个更高级的详细帮助信息。只需要使用一个有效的fs.Stats 方法名。下面的配置仅仅清理一个与模式匹配的真实的文件:

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

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

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

通配符模式

通常分别指定所有源文件路径是不切实际的,因此Grunt通过内置支持node-glob 和 minimatch 库来匹配文件名(又叫作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: ...}

更多关于通配符模式的语法,请查看node-glob 和 minimatch 的文档。

动态构建文件对象

当你希望处理大量的单个文件时,这里有一些附加的属性可以用来动态的构建一个文件列表。这些属性都可以用于CompactFiles 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_mappingsdynamic_mappings两个目标具有相同的src-dest文件映射列表, 这是因为任务运行时Grunt会自动展开dynamic_mappings文件对象为4个单独的静态src-dest文件映射--假设这4个文件能够找到。

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

grunt.initConfig({
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.initConfig({
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配置中的,并且grunt-contrib-uglify 插件中的 uglify 任务被配置用于压缩一个源文件以及使用该元数据动态的生成一个banner注释。

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

grunt.initConfig({
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'
}
}
});
Found an error in the documentation? File an issue.

grunt配置任务的更多相关文章

  1. Nodejs+Grunt配置SASS项目自动编译

    Nodejs+Grunt配置SASS项目自动编译 早前听说Nodejs和Grunt很强大,特别是用来构建自动化的前端开发,更是强大无比.但一直碍于自己掌握的技术有限,不敢深入,也未曾深入下去.最近在开 ...

  2. 我的grunt配置

    module.exports = function(grunt) { // 配置. grunt.initConfig({ pkg: grunt.file.readJSON('package.json' ...

  3. grunt配置详情

    这个grunt配置 是我的一个程序员朋友从网上无意间看到的,然后他亲测了下,恩,是可以的.不过我到目前还未测试过是否可以. 一.安装node, 首先确保电脑已有node的环境.然后 运行  npm i ...

  4. grunt配置太复杂?发布一个前端构建工具,简单高效,自动跳过未更新的文件

    做前端项目,如果没有一个自动化构建工具,手动处理那简直就是坑爹O(∩_∩)O.于是上网了解了下,grunt用的人不少,功能也挺强大.看了一下grunt的配置(包括gulp),感觉稍显复杂.当时项目结构 ...

  5. grunt配置太复杂?使用Qbuild进行文件合并、压缩、格式化等处理

    上次简单介绍了下Qbuild的特点和配置,其实实现一个自动化工具并不复杂,往简单里说,无非就是筛选文件和处理文件.但Qbuild的源码也并不少,还是做了不少工作的. 1. 引入了插件机制.在Qbuil ...

  6. grunt配置sass项目自动编译

    1.安装Ruby和SASS 首先我们需要在电脑上安装Ruby和SASS.如果您使用的是Mac,您就没必要安装Ruby.如果您使用的是Window系统,你需要安装Ruby. 2.安装Nodejs 由于使 ...

  7. 配置grunt进行css、js的检查、合并和压缩

    现在会进行代码的合并和压缩已成为前端人员的必备知识,那么现在来介绍一个grunt的工具.grunt是个风靡世界的工具,它的首页是  http://www.gruntjs.net 这是个中文网站,有文档 ...

  8. grunt安装、配置、在webstrom中使用

    1.全局范围安装 Grunt命令行(CLI) npm install -g grunt-cli Grunt CLI的任务很简单:调用与Gruntfile在同一目录中 Grunt.这样带来的好处是,允许 ...

  9. grunt项目配置

    安装完CLI,还要在项目安装Grunt npm install -g grunt-cli npm install grunt --save-dev 源码放在src下 package.json放在根目录 ...

随机推荐

  1. 告别被拒,如何提升iOS审核通过率(上篇)

    iOS审核一直是每款移动产品上架苹果商店时面对的一座大山,每次提审都像是一次漫长而又悲壮的旅行,经常被苹果拒之门外,无比煎熬.那么问题来了,我们有没有什么办法准确把握苹果审核准则,从而提升审核的通过率 ...

  2. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  3. Intellij idea添加单元测试工具

    1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...

  4. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  5. 深究标准IO的缓存

    前言 在最近看了APUE的标准IO部分之后感觉对标准IO的缓存太模糊,没有搞明白,APUE中关于缓存的部分一笔带过,没有深究缓存的实现原理,这样一本被吹上天的书为什么不讲透彻呢?今天早上爬起来赶紧找了 ...

  6. RabbitMq应用一

    RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...

  7. 深入理解javascript的getTime方法

    1.理解getTime getTime() 方法返回一个时间的格林威治时间数值. 可以使用这个方法把一个日期时间赋值给另一个Date 对象. 语法: dateObj.getTime() 参数: 无. ...

  8. Android SDK 在线更新镜像服务器资源

    本文转自:http://blog.kuoruan.com/24.html.感谢原作者. 什么是Android SDK SDK:(software development kit)软件开发工具包.被软件 ...

  9. 程序员必须要知道的Hadoop的一些事实

    程序员必须要知道的Hadoop的一些事实.现如今,Apache Hadoop已经无人不知无人不晓.当年雅虎搜索工程师Doug Cutting开发出这个用以创建分布式计算机环境的开源软...... 1: ...

  10. ecshop验证码

    <?php //仿制ecshop验证码(四位大写字母和数字.背景) //处理码值(四位大写字母和数字组成) //所有的可能的字符集合 $chars = 'ABCDEFGHIJKLMNOPQRST ...