May 25, 2021 Grunt
This guide explains how to use Gruntfile to configure task for your project. If you don't yet know what Gruntfile is, read the Quick Start guide and take a look at this Gruntfile example.
Grunt's task configuration is specified in the Gruntfile grunt.initConfig method. T his configuration is primarily a property named after a task name and can also contain any other data. Once these properties representing arbitrary data conflict with the properties required by the task, they are ignored.
In addition, since this is JavaScript in itself, you are not limited to using JSON; If necessary, you can even build configurations programmatically.
grunt.initConfig({
concat: {
// 这里是concat任务的配置信息。
},
uglify: {
// 这里是uglify任务的配置信息
},
// 任意数据。
my_property: 'whatever',
my_src_files: ['foo/*.js', 'bar/*.js'],
});
When a task is run, Grunt automatically looks for properties with the same name in the configuration object. M ultitas missions can define multiple configurations by any named target. In the following case, the concat task has two targets called foo and bar, while the uglify task has only one target called 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.
},
},
});
Specifying both tasks and targets, such as grunt concat:foo or grunt concat:bar, will only handle the configuration of the specified target, while running grunt concat will traverse all targets and process them in turn. Note that if a task has been renamed with grunt.task.renameTask, Grunt will look for properties named after the new task name in the configuration object.
In a task configuration, options properties can be used to specify default values that override built-in properties. I n addition, each target can have an options property specific to that target. Target-level flat options will override task-level options.
Options objects are optional and can be ignored if not needed.
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.
},
},
});
Since most tasks are file operations, Grunt has a powerful abstraction layer to declare which files the task should manipulate. T here are several ways to define src-dest (source-target file) file mapping, all of which provide varying degrees of description and control of how to operate. Any multitaser can understand the following format, so you just need to choose the format that meets your needs.
All file formats support src and dest properties, in addition to the Compact and Files Array formats, which also support some of the following additional properties:
This form allows one src-dest file map for each target. T ypically it is used for read-only tasks such as grunt-contrib-jshint, which require only a single src property and does not require the associated list option. This format also specifies additional properties for each src-dest file map.
grunt.initConfig({
jshint: {
foo: {
src: ['src/aa.js', 'src/aaa.js']
},
},
concat: {
bar: {
src: ['src/bb.js', 'src/bbb.js'],
dest: 'dest/b.js',
},
},
});
This form supports file mapping in the form of multiple src-dests for each target, with the property name the target file and the source file as its value (the list of source files is declared in array format). You can specify several src-dest file maps in this way, but you cannot specify additional properties for each map.
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'],
},
},
},
});
This form supports multiple src-dest file maps for each target, while also allowing each map to have additional properties:
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'},
],
},
},
});
The dest-as-target file format is a transition before multitasing and targeting occur, and the target file path is actually the target name. U nfortunately, because the target name is a file path, running the grunt task:target may not be appropriate. In addition, you cannot specify a target-level options or specify additional properties for each src-dest file map.
This format is no longer approved, please try not to use it.
grunt.initConfig({
concat: {
'dest/a.js': ['src/aa.js', 'src/aaa.js'],
'dest/b.js': ['src/bb.js', 'src/bbb.js'],
},
});
Filter properties can provide you with more advanced and detailed help information for your target file. O nly one valid fs. is required. T he name of the Stats method. The following configuration cleans up only one real file that matches the pattern:
grunt.initConfig({
clean: {
foo: {
src: ['tmp/**/*'],
filter: 'isFile',
},
},
});
Or create your own finder function to return true or false depending on whether the file matches. The following example will clean up only one empty directory:
grunt.initConfig({
clean: {
foo: {
src: ['tmp/**/*'],
filter: function(filepath) {
return (grunt.file.isDir(filepath) && require('fs').readdirSync(filepath).length === 0);
},
},
},
});
It is generally impractical to specify all source file paths separately, so Grunt matches file names (also known as globbing) with built-in support for node-glob and minimatch libraries.
However, this is not a comprehensive tutorial on matching patterns, you just need to know how to use them during file path matching:
What everyone needs to know is that foo/.js will match all files at the end of the .js in the foo/directory, and foo/s/js will match the foo/directory and all files ending in .js in its subdirect directory.
In addition, to simplify the already complex wildcard pattern, Grunt allows you to specify a file path in the form of an array or a wildcard pattern. A ll modes are processed sequentially, and patterns are processed with! T he files matched by the pattern of the prefix will not be included in the result set. And each item in the result set is unique.
For example:
// 指定单个文件:
{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: ...}
For more information on the syntax of wildcard patterns, check out the documentation for node-glob and minimatch.
When you want to work with a large number of individual files, here are some additional properties that you can use to dynamically build a list of files. These properties can be used in the Compact and File Array file mapping formats.
Expand is set to true to enable the following options:
In the following example, the static_mappings and dynamic_mappings targets in the uglify task have the same list of src-dest file maps because Grunt automatically expands them when the task runs dynamic_mappings the file object is mapped to four separate static src-dest files -- assuming that the four files can be found.
You can specify that any static src-dest and dynamic src-dest file maps are combined.
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
},
],
},
},
});
The template specified using the .lt;% %?gt; separator automatically extends the scan when the task reads the appropriate data from their configuration. The template is recursively expanded until the remaining template-related information (matching the template) no longer exists in the configuration.
The entire configuration object determines the property context (the properties in the template). In addition, the use of grunt in templates and its methods are valid, for example: slt;%=grunt.template.today ('yyyy-mm-dd') %?gt;.
Take the concat task configuration as an example, and run the grunt concat:sample to generate a file named build/abcde.js by matching all the files in the banner by foo/.js-bar/.js-bar/.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'],
});
In The following Gruntfile, the project's metadata is imported from the package.json file into the Grunt configuration, and the uglify task in the grunt-contrib-uglify plug-in is configured to compress a source file and generate a banner comment using the metadata dynamically.
Grunt has two methods, grunt.file.readJSON and grunt.file.readYAML, which are used to introduce JSON and YAML data, respectively.
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' } } });