您的位置:首页 > 其它

Grunt 入门指南2:任务配置

2013-05-16 02:03 525 查看

配置tasks

这份指南解释了在你的项目里怎么用Gruntfiile配置tasks。

Grunt 配置

task 配置通过grunt.initConfig 方法在Gruntfile中指定。配置主要是task-named 属性,但也会包含一些数据。

grunt.initConfig({
concat: {
// concat task configuration goes here.
},
uglify: {
// uglify task configuration goes here.
},
// Arbitrary non-task-specific properties.
my_property: 'whatever',
my_src_files: ['foo/*.js', 'bar/*.js'],
});


Task 配置和 Targets

当一个task执行,Grunt会查找配置上与此task同名的属性.多个task可以有多个配置,它们被叫做 “targets”.在下面这个例子中,
concat
foo
bar
两个 target,
uglify
只有一个
bar
target.

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.
},
},
});


grunt concat:foo
或者
grunt concat:bar
这样的task和target 只在指定的目标的配置上处理,当执行
grunt concat
时会迭代所有的targets,对每一个进行处理. 注意如果一个task被
grunt.renametask
方法重命名后,Grunt将会按新的名字来寻找配置对象。

Options

在task配置中,指定
options
属性会覆盖内置的默认
options
. 并且每个target都可以指定一个
options
属性.Target级的options会覆盖Task级的options.

options
属性是可选的,如果不需要可以省略.

grunt.initConfig({
concat: {
options: {
// Task-level options may go here, overriding task defaults.
},
foo: {
options: {
// "foo" target options may go here, overriding task-level options.
},
},
bar: {
// No options specified; this target will use task-level options.
},
},
});


Files

因为大量的tasks都需要执行文件操作,Grunt提供了强大的文件操作能力. 有很多种方式去定义src-dest(源码-目标)文件映射,可以在不同角度进行控制. 每个task都理解以下的格式, 你可以按需选择.

所有的文件格式都支持
src
dest
, 但是"Compact"和"Files Array"格式支持一些附加的属性:

filter
src里的路径通过任意一个有效的
fs.Stats
函数名或者一个函数通过返回
true
false
决定是否匹配

nonull
当一个匹配没有找到时,返回包含这个模式的列表自身.当没有任何一个匹配时,返回一个空列表.结合grunt 的
--verbore
参数,这个选项可以帮助debug文件的路径问题.

dot
即使模式没有包含开始的
.
,
dot
匹配文件名时也会开始于
.


matchBase
如果设置了, 模式在带有斜杠的文件名中,只会最后一个结尾的文件名,比如, a?b 只会匹配
/xyz/123/acb
, 但不会匹配
xyz/acb/123


expand
提供一个动态的 src-dest 文件映射, 细节请看 "Building the files object dynamically"

其他的参数只在某些识别它的库中使用. 更多细节可以参考 node-glob 和 minimatch 文档

Compact Format

这种形式允许一个独立的 src-dest 文件映射到每个target. 通常用于只读的tasks, 像 grunt-contrib-jslint, 只有
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',
},
},
});


Files Object Format

这种形式支持在一个target里放多个 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'],
},
},
},
});


File Array Format

这个形式也支持一个target里放多个 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'},
],
},
},
});


Older Format

dest-as-target (target里直接定义dest) 格式是历史遗留的格式,目标文件路径即是target的名字. 不幸的是,因为target名字就是路径,执行
grunt task:target
就变得很尴尬. 同样,你也不能在每个src-dest文件映射上指定一个target级别的options或者附加属性.

考虑到这种格式已经被废弃,请不要使用它.

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


Custom Filter Function

filter
属性可以在细节上帮你定位文件. 最简单的是使用一个有效的 fs.Status 函数. 下例中将会只匹配真正的文件:

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);
},
},
},
});


Globbing patterns

很多情况下我们不会指定所有文件的明确路径,所以Grunt 通过内置的 node-glob 和 minimatch 库支持文件名扩展(也就是文件名通配).

常用的通配模式有: *
*
匹配任意数量的字符,但不匹配
/
*
?
匹配单个字符,但不匹配
/
*
**
匹配任意长度的字符,包括
/
,只要它是路径的唯一部分. *
{}
允许用逗号分割一个'或'关系的列表 *
!
在开头表示这个模式是反向的

大多数人们需要知道
foo/*.js
会匹配所有在
foo/
目录中结尾为
.js
的文件,但是
foo/**/*.js
会匹配
foo/
文件夹以及它的所有子孙级文件夹中结尾为
.js
的文件.

同样,对于复杂的通配模式,Grunt允许使用文件路径或者通配模式数组. 在
!
前缀的模式从结果集中排除匹配的文件,所有模式将被按序预处理.结果集是去重的。

例子:

// You can specify single files:
{src: 'foo/this.js', dest: ...}
// Or arrays of files:
{src: ['foo/this.js', 'foo/that.js', 'foo/the-other.js'], dest: ...}
// Or you can generalize with a glob pattern:
{src: 'foo/th*.js', dest: ...}

// This single node-glob pattern:
{src: 'foo/{a,b}*.js', dest: ...}
// Could also be written like this:
{src: ['foo/a*.js', 'foo/b*.js'], dest: ...}

// All .js files, in foo/, in alpha order:
{src: ['foo/*.js'], dest: ...}
// Here, bar.js is first, followed by the remaining files, in alpha order:
{src: ['foo/bar.js', 'foo/*.js'], dest: ...}

// All files except for bar.js, in alpha order:
{src: ['foo/*.js', '!foo/bar.js'], dest: ...}
// All files in alpha order, but with bar.js at the end.
{src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: ...}

// Templates may be used in filepaths or glob patterns:
{src: ['src/<%= basename %>.js'], dest: 'build/<%= basename %>.min.js'}
// But they may also reference file lists defined elsewhere in the config:
{src: ['foo/*.js', '<%= jshint.all.src %>'], dest: ...}


想要看更多的通配模式语法,可以参考node-glob和minimatch文档。

Building the files object dynamically

当你想要处理很多独立的文件, 有些附加的属性可能用于动态构建文件列表.以下属性可以指定在"Compact"和"Files Array"映射格式中.

expand
设置为
true
开启以下的选项:

cwd
所有
src
匹配都相对于(但不包含)这个路径

src
模式匹配时相对于
cwd


dest
目标文件路径前缀

ext
在生成的
dest
路径中替换所有存在的扩展名为这个值

flatten
将生成
dest
路径移除所有路径部分

rename
这个函数会被每个
src
路径调用(在扩展被改名和flatten之后).
dest
和匹配的
src
路径会当参数传进去,这个函数必须返回一个新的
dest
值. 如果同样的
dest
被多次返回,每次
src
都会用它添加到源码的数组中去.

下面的例子中,
minify
task在
sratic_mappings
dynamic_mappings
targets 会看到同样的src-dest列表, 因为Grunt 会自动的扩展
dynamic_mappings
文件对象把四个单独的文件放入 src-dest 文件映射,加入4个文件可以在task执行的时候被找到的话.

静态和动态的文件映射可以随便结合着用.

grunt.initConfig({
minify: {
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 "minify" 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.
},
],
},
},
});


Templates

模版使用
<% %>
分割符,并且在tasks读入它的配置后自动扩展.模式会递归的扩展.

整个配置对象是每个确定的属性的上下文. 此外,
grunt
在模版内提供了它的方法,比如
<%= grunt.template.today('yyyy-mm-dd') %>


<%= prop.subprop %>
被展开为配置中的
prop.subprop
的值,而不用管类型.模版可以使用引用或者值类型.

<% %>
可以指定任意的一行javascript代码, 在控制流程和循环的时候很有用

下面给出一个
concat
task配置的例子, 执行
grunt concat:sample
将会产生一个名为
build/abcde.js
文件,这个文件用banner
/* abcde */
连接了所有匹配的文件
foo/*.js
+
bar/*.js
+
baz/*.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'
},
},
// Arbitrary properties used in task configuration templates.
foo: 'c',
bar: 'b<%= foo %>d', // 'bcd'
baz: 'a<%= bar %>e', // 'abcde'
qux: ['foo/*.js', 'bar/*.js'],
});


Import External Data

在下面的Gruntfile中, 项目元数据是从
package.json
中导入的,并且 grunt-contrib-uglify 插件
uglify
task 配置为压缩源码并且动态使用元数据添加banner.

Grunt 拥有
grunt.file.readJSON
grunt.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'
}
}
});


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: