Grunt - 快速指南
Grunt - 概述
什么是 Grunt?
Grunt 是一个 JavaScript 任务运行器,可用作 JavaScript 对象的命令行工具。它是一个基于 NodeJS 编写的任务管理器。
为什么使用 Grunt?
Grunt 可以非常轻松地执行重复性任务,例如编译、单元测试、压缩文件、运行测试等。
Grunt 包含内置任务,可扩展您的插件和脚本的功能。
Grunt 的生态系统非常庞大;您可以用很少的努力实现任何自动化。
历史
2011 年,GruntJS 添加了第一行源代码。Grunt v0.4 于 2013 年 2 月 18 日发布。Grunt v0.4.5 于 2014 年 5 月 12 日发布。Grunt 的稳定版本是 1.0.0 rc1,于 2016 年 2 月 11 日发布。
优势
使用 Grunt,您可以轻松执行文件的压缩、编译和测试。
Grunt 统一了 Web 开发人员的工作流程。
您可以使用 Grunt 轻松处理新的代码库,因为它包含的基础设施更少。
它加快了开发工作流程并提升项目的性能。
缺点
每当 npm 包更新时,您需要等待 Grunt 的作者更新它。
每个任务都是为了完成指定的工作而设计的。如果您想扩展指定的任务,那么您需要使用一些技巧来完成工作。
Grunt 包含大量针对单个插件的配置参数。通常,Grunt 配置文件的长度较长。
Grunt - 功能
Grunt 是一个基于 JavaScript 的任务运行器,这意味着它可以自动执行工作流中的重复任务,并且可以用作 JavaScript 对象的命令行工具。
GruntJS 的一些最突出的功能如下 −
Grunt 使工作流变得像编写设置文件一样简单。
您可以用最少的努力自动执行重复任务。
Grunt 是一个基于 NodeJS 的流行任务运行器。它灵活且被广泛采用。
它采用简单的方法,包括 JS 中的任务和 JSON 中的配置。
Grunt 压缩 JavaScript、CSS 文件、测试文件、编译 CSS 预处理器文件(SASS、LESS)等。
Grunt 包含内置任务,可扩展插件和脚本的功能。
它加快了开发工作流程并提高了项目的性能。
您可以使用 Grunt 轻松处理新的代码库,因为它包含的基础设施更少。
Grunt 的生态系统非常庞大;您可以用很少的努力实现任何自动化。
Grunt 减少了执行重复任务时出错的可能性。
Grunt 目前有超过 4000 个插件。
它可以用于大型生产站点。
Grunt - 安装
本章逐步介绍如何在您的系统上安装 Grunt。
Grunt 的系统要求
操作系统 − 跨平台
浏览器支持 − IE (Internet Explorer 8+)、Firefox、Google Chrome、Safari、Opera
Grunt 的安装
步骤 1 − 我们需要 NodeJs 来运行 Grunt。要下载 NodeJs,请打开链接 https://nodejs.org/en/,您将看到如下所示的屏幕 −
下载 Latest Features 版本的 zip 文件。
步骤 2 − 接下来,运行安装程序以在您的计算机上安装 NodeJs。
步骤 3 −接下来,您需要设置环境变量。
路径用户变量
- 右键单击我的电脑。
- 选择属性。
- 接下来,选择高级选项卡并单击环境变量。
在环境变量窗口下,双击屏幕中显示的PATH。
您将看到如图所示的编辑用户变量窗口。在变量值字段中添加 NodeJs 文件夹路径为 C:\Program Files odejs ode_modules pm。如果已经为其他文件设置了路径,则需要在后面加上分号(;)并添加 NodeJs 路径,如下所示 −
最后,单击 OK 按钮。
系统变量
在 System Variables 下,双击 Path,如下图所示。
您将获得一个 Edit System Variable 窗口,如下所示。在变量值字段中添加 NodeJs 文件夹路径为 C:\Program Files odejs\,然后单击确定,如下所示 −
步骤 4 − 要在系统上安装 grunt,您需要全局安装 Grunt 的命令行界面 (CLI),如下所示 −
npm install -g grunt-cli
运行上述命令会将 grunt 命令放入您的系统路径中,这样就可以从任何目录运行它。
安装 grunt-cli 不会安装 Grunt 任务运行器。 grunt-cli 的作用是运行已安装在 Gruntfile 旁边的 Grunt 版本。它允许一台机器同时安装多个版本的 Grunt。
步骤 5 − 现在,我们将创建 配置文件 以运行 Grunt。
package.json
package.json 文件位于项目的根目录中,位于 Gruntfile 旁边。每当您在与 package.json 相同的文件夹中运行命令 npm install 时,package.json 都会用于正确运行每个列出的依赖项。
可以在命令提示符中键入以下命令来创建基本的 package.json −
npm init
基本的 package.json 文件将如下所示 −
{
"name": "tutorialspoint",
"version": "0.1.0",
"devDependencies": {
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0"
}
}
您可以通过以下命令将 Grunt 和 gruntplugins 添加到现有的 pacakge.json 文件中 −
npm install <module> --save-dev
在上述命令中,<module> 表示要本地安装的模块。上述命令还会将 <module>到 devDependencies。
例如,以下命令将安装最新版本的 Grunt 并将其添加到您的 devDependencies −
npm install grunt --save-dev
Gruntfile.js
Gruntfile.js 文件用于定义我们的 Grunt 配置。它是我们写入设置的地方。基本的 Gruntfile.js 文件如下所示 −
// 我们的包装函数(grunt 及其插件所需)
// 所有配置都位于此函数内
module.exports = function(grunt) {
// CONFIGURE GRUNT
grunt.initConfig({
// 从 package.json 文件获取配置信息
// 这样我们就可以使用名称和版本 (pkg.name) 之类的内容
pkg: grunt.file.readJSON('package.json'),
// 我们所有的配置都在这里
uglify: {
// uglify 任务配置
options: {},
build: {}
}
});
// log something
grunt.log.write('Hello world! Welcome to Tutorialspoint!!
');
// 加载提供"uglify"任务的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');
// 默认任务。
grunt.registerTask('default', ['uglify']);
};
Grunt - 入门
要使用 Grunt,您需要安装 Node.js。Node.js 的安装已在上一章中说明。您可以使用 Node.js 包管理器安装 Grunt 和 Grunt 插件。
在系统上设置 Grunt 之前,您可以使用以下命令更新 Node 包管理器 −
npm update -g npm
如果您使用的是 Mac 或 Linux,则需要在命令行开头使用 sudo 字样来授予管理员访问权限,如下所示 −
sudo npm update -g npm
CLI 安装
CLI 代表命令行界面,运行已安装的 Grunt 版本。要开始使用 Grunt,您需要全局安装 Grunt 的命令行界面 (CLI),如下所示 −
npm install -g grunt-cli
运行上述命令会将 grunt 命令放入您的系统路径中,这使得它可以从任何目录运行。您无法通过安装 grunt-cli 来安装 Grunt 任务运行器。它允许一台机器同时安装多个版本的 Grunt。
CLI 的工作原理
每当运行 Grunt 时,CLI 都会使用 require() 系统在您的系统上查找已安装的 Grunt。使用 grunt-cli,您可以从项目中的任何目录运行 Grunt。如果您使用的是本地安装的 Grunt,那么 grunt-cli 将使用本地安装的 Grunt 库并应用 Grunt 文件中的配置。
使用现有和新项目
如果您使用的是已配置的项目,其中包含 package.json 和 Gruntfile,请按照下面指定的简单步骤操作 −
- 找到项目根目录的路径。
- 您可以使用 npm install 命令安装依赖项。
- 使用 grunt 命令运行 Grunt。
如果您正在创建新项目,则将两个文件 package.json 和 Gruntfile 包含到您的项目中。
package.json − package.json 文件位于项目的根目录中,每当您在同一文件夹中运行 npm install 命令时,它都会用于运行每个列出的依赖项。
Gruntfile.js − Gruntfile.js 文件用于编写项目的配置设置。
package.json
package.json 文件位于项目的根目录中,位于 Gruntfile 旁边,每当您在同一文件夹中运行 npm install 命令时,它都会用于运行每个列出的依赖项。
您可以通过以下列出的不同方式创建 package.json −
- 您可以 grunt-init 创建 package.json 文件。
- 您还可以使用 npm-init 命令创建 package.json 文件。
您可以按如下所示编写规范 −
{
"name": "tutorialspoint",
"version": "0.1.0",
"devDependencies": {
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0"
}
}
您可以使用以下命令 − 将 Grunt 和 gruntplugins 添加到现有的 pacakge.json 文件中
npm install <module> --save-dev
此处,<module> 表示要在本地安装的模块。上述命令将安装指定的模块并自动将其添加到 devDependencies 部分。
例如,以下命令将安装最新版本的 Grunt 并将其添加到您的 devDependencies −
npm install grunt --save-dev
Gruntfile
Gruntfile.js 文件是 Grunt 配置设置的默认位置。 Grunt 文件包含以下部分 −
- 包装函数
- 项目和任务配置
- 加载 Grunt 插件和任务
- 自定义任务
基本的 Gruntfile.js 文件如下所示 −
// 我们的包装函数(grunt 及其插件所需)
// 所有配置都位于此函数内
module.exports = function(grunt) {
// 配置 GRUNT
grunt.initConfig({
// 从 package.json 文件获取配置信息
// 这样我们就可以使用名称和版本 (pkg.name) 之类的内容
pkg: grunt.file.readJSON('package.json'),
// 我们所有的配置都在这里
});
// 加载提供"uglify"任务的插件
grunt.loadNpmTasks('grunt-contrib-uglify');
// 默认任务
grunt.registerTask('default', ['uglify']);
};
包装函数
在上面的代码中,module.exports 是一个包装函数,整个配置都放在这个函数中。这是一种向应用程序其余部分显示配置的方式。
module.exports = function(grunt) {
//在这里做与 grunt 相关的事情
}
项目和任务配置
一旦您的 Grunt 配置准备就绪,您就可以配置 Grunt 任务。项目配置可以在 grunt.initConfig() 部分中编写。在 grunt.initConfig() 函数中,从 package.json 文件中获取配置信息并将其保存到 pkg。您可以使用 pkg.name 调用您的项目名称,并使用 pkg.version 调用版本。
加载 Grunt 插件和任务
使用 grunt.loadNpmTasks 方法从指定插件加载任务。您可以使用 npm 在本地安装插件,并且它必须与 Gruntfile 相关。您可以使用如下所示的简单命令加载插件 −
grunt.task.loadNpmTasks(pluginName)
自定义任务
当您通过命令行运行 Grunt 时,Grunt 将查找 default 任务。在上面的代码中,我们使用了一个名为 uglify 的任务,可以使用 grunt 命令运行。这与明确运行 grunt uglify 命令相同,您可以指定数组中的任务数。
grunt.registerTask('default', ['uglify']);
Grunt - 配置任务
您可以在 Gruntfile.js 文件 中为 Grunt 定义项目特定的配置数据。
Grunt 配置
可以使用 grunt.initConfig() 方法在 Gruntfile 中初始化任务配置数据。在 grunt.initConfig() 函数中,从 package.json 文件中获取配置信息。配置将包含一个名为 properties 的任务和任意数据。
grunt.initConfig({
jshint: {
// jshint 任务的配置
},
cssmin: {
// cssmin 任务的配置
},
// 任意非任务特定属性
my_files: ['dir1/*.js', 'dir2/*.js'],
});
任务配置和目标
当您运行任务时,Grunt 会在名为任务的属性下查找配置。我们将定义具有多个配置和目标选项的任务,如下所示 −
grunt.initConfig({
jshint:{
myfile1:{
//"myfile1"目标选项的配置
},
myfile2:{
//"myfile2"目标选项的配置
},
},
cssmin:{
myfile3:{
//"myfile3"目标选项的配置
},
},
});
此处,jshint 任务具有 myfile1 和 myfile2 目标,而 cssmin 任务具有 myfile3 目标。当您运行 grunt jshint 时,它将遍历任务和目标以处理指定目标的配置。
选项
在任务配置中定义 options 属性,该属性将覆盖任务默认值。每个目标都包含 options 属性,该属性将覆盖任务级选项。它将具有以下格式 −
grunt.initConfig({
jshint: {
options: {
// 覆盖任务默认值的任务级选项
},
myfile: {
options: {
// "myfile"目标选项覆盖任务默认值
},
},
myfile1: {
// 没有选项,目标将使用任务级选项
},
},
});
文件
Grunt 提供了一些指定任务应该操作哪些文件的想法,并使用不同的方式来指定 src-dest 文件映射。以下是 src 和 dest 映射支持的一些附加属性 −
filter − 它是一个指定匹配的 src 文件路径并返回 true 或 false 值的函数。
nonull − 当它设置为 true 时,它定义不匹配的模式。
dot − 它匹配以句点或其他方式开头的文件名。
matchBase −它将包含斜杠的模式与路径的基本名称进行匹配。
expand − 它处理 src-dest 文件映射。
紧凑格式
它指定每个目标的 src-dest 文件映射,可用于只读任务,并且只需要 src 属性,而不需要 dest 属性。
grunt.initConfig({
jshint: {
myfile1: {
src: ['src/file1.js','src/file2.js']
},
},
cssmin: {
myfile2: {
src: ['src/file3.js','src/file4.js'],
dest: 'dest/destfile.js',
},
},
});
文件对象格式
它指定每个目标的 src-dest 文件映射,其中属性名称为 dest 文件,其值为 src 文件。
grunt.initConfig({
jshint: {
myfile1: {
files: {
'dest/destfile.js':['src/file1.js','src/file2.js'],
'dest/destfile1.js':['src/file3.js','src/file4.js'],
},
},
myfile2: {
files: {
'dest/destfile2.js':['src/file22.js','src/file23.js'],
'dest/destfile21.js':['src/file24.js','src/file25.js'],
},
},
},
});
文件数组格式
它通过使用每个映射的附加属性来指定每个目标的 src-dest 文件映射。
grunt.initConfig({
jshint: {
myfile1: {
files: [
{src:['src/file1.js','src/file2.js'],dest:'dest/file3.js'},
{src:['src/file4.js','src/file4.js'],dest:'dest/file5.js'},
],
},
myfile2: {
files: [
{src:['src/file6.js','src/file7.js'],dest:'dest/file8/', nonull:true},
{src:['src/file9.js','src/file10.js'],dest:'dest/file11/', filter:'isFalse'},
],
},
},
});
旧格式
在多任务出现之前,dest-as-target 文件格式就已经存在,其中目标文件路径是目标的名称。以下格式已弃用,并且不会在代码中使用。
grunt.initConfig({
jshint: {
'dest/destfile2.js':['src/file3.js','src/file4.js'],
'dest/destfile5.js':['src/file6.js','src/file7.js'],
},
});
自定义过滤功能
您可以使用 filter 属性帮助目标文件获得更详细的信息。以下格式仅在与实际文件匹配时才清除文件。
grunt.initConfig({
clean: {
myfile:{
src: ['temp/**/*'],
filter: 'isFile',
},
},
});
通配符模式
通配符意味着扩展文件名。Grunt 使用内置的 node-glob 和 minimatch 库 支持通配符。通配符模式包括以下几点 −
- * 匹配任意数量的字符,但不匹配 /。
- ? 匹配单个字符,但不匹配 /。
- ** 匹配多个字符,包括 /。
- { 指定逗号分隔的"或"表达式列表。
- ! 将在开头否定模式匹配。
例如 −
{src: 'myfile/file1.js', dest: ...} // 它指定单个文件
{src: 'myfile/*.js', dest: ...} // 它匹配所有以 .js 结尾的文件
{src: 'myfile/{file1,file2}*.js', dest: ...} // 定义单个节点 glob 模式
{src: ['myfile/*.js', '!myfile/file1.js'], dest: ...} // 所有文件将按字母顺序显示
// 除 file1.js 之外
动态构建文件对象
当您处理单个文件时,您可以使用其他属性来动态构建文件列表。当您将 expand 属性设置为 true 时,它将启用以下某些属性 −
cwd 匹配此路径的所有 src。
src 匹配要匹配的模式,相对于 cwd。
dest 属性指定目标路径前缀。
ext 将使用在 dest 路径中生成的值替换现有扩展。
extDot 表示表示扩展的句点所在的位置。它使用 first 句点或 last 句点;默认情况下,它被设置为第一个句点
flatten从dest路径中删除所有路径部分。
rename指定一个包含新目标和文件名的字符串。
重命名属性
它是一个独特的 JavaScript 函数,它返回一个字符串,您不能使用字符串值进行重命名。在以下示例中,copy任务将创建 README.md 的备份。
grunt.initConfig({
copy: {
backup: {
files: [{
expand: true,
src: ['docs/README.md'], // 创建 README.md 的备份
rename: function () { // 指定重命名函数
return 'docs/BACKUP.txt'; // 返回包含完整目的地的字符串
}
}]
}
}
});
模板
您可以使用 <% %> 分隔符指定模板。从配置中读取时,它们将自动扩展。它包括两种类型的属性 −
<%= prop.subprop %> 属性用于扩展配置中 prop.subprop 的值,该值可以引用字符串值、数组和其他对象。
<% %> 属性执行用于控制流或循环的内联 JavaScript 代码。
例如 −
grunt.initConfig({
concat: {
myfile: {
options: {
banner: '/* <%= val %> */
',
},
src: ['<%= myval %>', 'file3/*.js'],
dest: 'build/<%= file3 %>.js',
},
},
// 任务配置模板中使用的属性
file1: 'c',
file2: 'b<%= file1 %>d',
file3: 'a<%= file2 %>e',
myval: ['file1/*.js', 'file2/*.js'],
});
导入外部数据
您可以从 package.json 文件 导入外部数据。grunt-contrib-uglify 插件可用于缩小源文件,并使用元数据创建横幅评论。您可以使用 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") %> */
'
},
dist: {
src: 'src/<%= pkg.name %>.js',
dest: 'dist/<%= pkg.name %>.min.js'
}
}
});
Grunt - 示例文件
在本章中,让我们使用以下插件创建一个简单的 Grunt 文件 −
- grunt-contrib-uglify
- grunt-contrib-concat
- grunt-contrib-jshint
- grunt-contrib-watch
安装上述所有插件并按照以下步骤创建一个简单的 Gruntfile.js −
步骤 1 − 您需要创建一个 wrapper 函数,该函数封装了 Grunt 的配置。
module.exports = function(grunt) {};
步骤 2 − 初始化您的配置对象,如下所示 −
grunt.initConfig({});
步骤 3 − 接下来,将 package.json 文件中的项目设置读入 pkg 属性。它使我们能够引用 package.json 文件中的属性值。
pkg: grunt.file.readJSON('package.json')
步骤 4 − 接下来,您可以定义任务的配置。让我们创建第一个任务 concat 来连接 src/ 文件夹中存在的所有文件,并将连接的 .js 文件存储在 dist/ 文件夹下。
concat: {
options: {
// 定义一个字符串,插入到连接输出的文件之间
separator: ';'
},
dist: {
// 文件需要连接
src: ['src/**/*.js'],
// 连接的输出 JS 文件的位置
dest: 'dist/<%= pkg.name %>.js'
}
}
步骤 5 −现在,让我们创建另一个名为 uglify 的任务来压缩我们的 JavaScript。
uglify: {
options: {
// 横幅将插入到显示日期和时间的输出顶部
banner: '/*! <%= pkg.name %> <%= grunt.template.today() %> */
'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
}
上述任务在 dist/ 文件夹中创建一个文件,其中包含已压缩的 .js 文件。<%= concat.dist.dest %> 将指示 uglify 压缩 concat 任务生成的文件。
第 6 步 − 让我们通过创建 jshint 任务来配置 JSHint 插件。
jshint: {
// 定义要进行 lint 的文件
files: ['Gruntfile.js', 'src/**/*.js'],
// 配置 JSHint
options: {
// 如果你想覆盖 JSHint 默认值,这里有更多选项
globals: {
jQuery: true,
}
}
}
上述 jshint 任务接受文件数组,然后接受选项对象。上述任务将查找 Gruntfile.js 和 src/**/*.js 文件中是否存在任何编码违规。
第 7 步 − 接下来,我们有 watch 任务,该任务查找任何指定文件中的更改并运行您指定的任务。
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
第 8 步 − 接下来,我们必须加载已通过 _npm 安装的所有 Grunt 插件。
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
第 9 步 − 最后,我们必须定义 default 任务。
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
只需在命令行中输入 grunt 命令即可运行 default 任务。
这是完整的 Gruntfile.js −
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today() %> */
'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
jshint: {
// 定义要进行 lint 的文件
files: ['Gruntfile.js', 'src/**/*.js'],
// 配置 JSHint
options: {
// 如果你想覆盖 JSHint 默认值,这里有更多选项
globals: {
jQuery: true,
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
};
Grunt - 创建任务
在本章中,让我们了解创建任务。每当您运行 Grunt 时,都会指定一个或多个要运行的任务,以通知 Grunt 您希望它做什么。如果您指定默认任务,则它将默认运行。
别名任务
每当指定任务列表时,一个或多个其他任务都可以由新任务别名。运行别名将依次运行taskList中的每个指定任务。 taskList 参数应为如下所示的任务数组 −
grunt.registerTask(taskName, [description, ] taskList)
例如,当您使用 jshint、concat 和 uglify 任务定义 taskList 并将 taskName 指定为 default 时,如果在未指定任何任务的情况下执行 Grunt,则所有列出的任务都将自动运行。
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
您还可以指定任务参数,如下所示 −
grunt.registerTask('dist', ['concat:dist', 'uglify:dist']);
在上面的任务中,别名 dist 同时运行 concat 和 uglify 任务。
多任务
每当您运行多个任务时,Grunt 都会在 Grunt 配置中搜索同名的属性。这些任务可以有多个配置,这些配置将使用任意命名的目标进行定义。
当您同时指定任务和目标时,将仅处理指定的目标配置。
grunt concat:foo
上述命令将仅运行目标foo。
当您仅指定任务时,将处理所有目标。
grunt concat
上述命令将遍历concat任务的所有目标。
当您使用grunt.task.renameTask重命名任务时,Grunt 会在配置对象中搜索具有new任务名称的属性。
grunt.initConfig({
log: {
foo: [1, 2, 3],
bar: 'Welcome to tutorialspoint',
sap: true
}
});
grunt.registerMultiTask('log', 'Log stuff.', function() {
grunt.log.writeln(this.target + ': ' + this.data);
});
在上面的例子中,如果 Grunt 是通过 grunt log:foo 运行的,多任务将记录 foo: 1,2,3,或者每当通过 grunt log:bar 运行时,它将记录 bar: Welcome to tutorialspoint。当 Grunt 作为 grunt log 运行时,它将记录 foo: 1,2,3,然后记录 bar: Welcome to tutorialspoint,然后记录 sap: true。
基本任务
每当您运行基本任务时,Grunt 都不会搜索配置或环境。相反,它运行指定的任务函数,并将指定的任何冒号分隔的参数作为函数参数传递。
grunt.registerTask(taskName, [description, ] taskFunction)
在下面的例子中,如果 Grunt 通过 grunt foo:testing:123 命令执行,则任务会记录 foo, testing 123。每当任务以 grunt foo 的形式运行时不带参数时,任务将 记录 foo, no args。
grunt.registerTask('foo', 'A simple task to logs stuff.', function(arg1, arg2) {
if (arguments.length === 0) {
grunt.log.writeln(this.name + ", no args");
} else {
grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);
}
});
自定义任务
如果您不想遵循多任务结构,您可以定义自定义任务,如下所示 −
grunt.registerTask('default', 'My "default" task description.', function() {
grunt.log.writeln('Currently running the "default" task.');
});
可以在另一个任务中运行一个任务,如下所示 −
grunt.registerTask('foo', 'My "foo" task.', function() {
// 将 bar 和 baz 任务排入队列,在 foo 完成后按顺序运行。
grunt.task.run('bar', 'baz');
// Or:
grunt.task.run(['bar', 'baz']);
});
您还可以创建异步任务,如下所示 −
grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() {
// 强制任务进入异步模式并获取 done() 函数的句柄。
var done = this.async();
// 运行一些同步内容。
grunt.log.writeln('Processing your task..');
// 运行一些异步内容。
setTimeout(function() {
grunt.log.writeln('Finished!');
done();
}, 1000);
});
您可以创建可以访问其名称和参数的任务,如下所示−
grunt.registerTask('foo', 'My task "foo" .', function(a, b) {
grunt.log.writeln(this.name, a, b);
});
// Usage:
// grunt foo
// logs: "foo", undefined, undefined
// grunt foo:bar
// logs: "foo", "bar", undefined
// grunt foo:bar:baz
// logs: "foo", "bar", "baz"
您可以以这样的方式创建任务,每当记录任何错误时,任务就会失败,如下所示 −
grunt.registerTask('foo', 'My task "foo" .', function() {
if (failureOfSomeKind) {
grunt.log.error('This is an error message.');
}
// 如果此任务有错误则返回 false 并失败
if (ifErrors) { return false; }
grunt.log.writeln('This is success message');
});
每当一个任务失败时,除非指定了 --force,否则所有后续任务都将被终止。
grunt.registerTask('foo', 'My task "foo" .', function() {
// Fail synchronously.
return false;
});
grunt.registerTask('bar', 'My task "bar" .', function() {
var done = this.async();
setTimeout(function() {
// Fail asynchronously.
done(false);
}, 1000);
});
任务可以依赖于其他任务才能成功执行。请记住,grunt.task.requires 实际上不会执行其他任务,而是仅检查它是否已执行且没有失败。
grunt.registerTask('foo', 'My task "foo" .', function() {
return false;
});
grunt.registerTask('bar', 'My task "bar" .', function() {
// 如果 foo 任务失败或从未运行,则任务失败。
grunt.task.requires('foo');
// 如果 foo 任务成功执行,则执行此代码。
grunt.log.writeln('Hello, World.. Welcome to Tutorialspoint!..');
});
// 用法:
// grunt foo bar 不记录,因为 foo 执行失败。
// **注意:这是一个空格分隔的顺序命令的示例,
//(类似于执行两行代码:`grunt foo` 然后 `grunt bar`)
// grunt bar 不记录,因为 foo 从未运行。
只要找不到所需的配置属性,任务甚至可能会失败。
grunt.registerTask('foo', 'My task "foo" .', function() {
// 如果缺少 meta.name 配置属性,则任务失败
// 格式 1:字符串
grunt.config.requires('meta.name');
// 或格式 2:数组
grunt.config.requires(['meta', 'name']);
// 有条件地记录...。
grunt.log.writeln('This only log if meta.name is defined in the config.');
});
任务可以访问配置属性,如下所示−
grunt.registerTask('foo', 'My task "foo" .', function() {
// 记录属性的值。如果属性未定义,则返回 null。
grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name'));
// 还记录属性的值。如果属性未定义,则返回 null。
grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name']));
});

