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 - 我们需要 NodeJ 来运行 Grunt。要下载 NodeJs,请打开链接https://nodejs.org/en/,您将看到如下所示的屏幕 -
下载zip 文件的最新功能版本。
步骤 2 - 接下来,运行安装程序以在计算机上安装NodeJ 。
步骤 3 - 接下来,您需要设置环境变量。
路径用户变量
- 右键单击我的电脑。
- 选择属性。
- 接下来,选择“高级”选项卡并单击“环境变量”。
在环境变量窗口下,双击PATH,如屏幕所示。
您将看到一个编辑用户变量窗口,如图所示。在变量值字段中添加 NodeJs 文件夹路径为C:\Program Files\nodejs\node_modules\npm。如果已经为其他文件设置了路径,则需要在其后添加分号(;)并添加 NodeJs 路径,如下所示 -
最后,单击“确定”按钮。
系统变量
在“系统变量”下,双击“路径”,如下图所示。
您将看到一个编辑系统变量窗口,如图所示。在变量值字段中添加 NodeJs 文件夹路径为C:\Program Files\nodejs\并单击确定,如下所示 -
步骤 4 - 要在系统上安装 grunt,您需要全局安装 Grunt 的命令行界面(CLI),如下所示 -
npm install -g grunt-cli
运行上述命令会将grunt命令放入您的系统路径中,这使得它可以从任何目录运行。
安装grunt-cli不会安装 Grunt 任务运行程序。grunt-cli的作用是运行已安装在Gruntfile旁边的 Grunt 版本。它允许一台机器同时安装多个版本的 Grunt。
步骤 5 - 现在,我们将创建配置文件以运行 Grunt。
包.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并将其添加到您的devDependency中-
npm install grunt --save-dev
Gruntfile.js
Gruntfile.js文件用于定义 Grunt 的配置。这是我们的设置将被写入的地方。基本的Gruntfile.js文件如下所示 -
// our wrapper function (required by grunt and its plugins) // all configuration goes inside this function module.exports = function(grunt) { // CONFIGURE GRUNT grunt.initConfig({ // get the configuration info from package.json file // this way we can use things like name and version (pkg.name) pkg: grunt.file.readJSON('package.json'), // all of our configuration goes here uglify: { // uglify task configuration options: {}, build: {} } }); // log something grunt.log.write('Hello world! Welcome to Tutorialspoint!!\n'); // Load the plugin that provides the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). 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 代表命令行界面,运行已安装的 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 文件用于编写项目的配置设置。
包.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并将其添加到您的devDependency中-
npm install grunt --save-dev
Grunt文件
Gruntfile.js文件是 Grunt 配置设置的默认位置。Grunt 文件包括以下部分 -
- 包装函数
- 项目和任务配置
- 加载 Grunt 插件和任务
- 自定义任务
基本的Gruntfile.js文件如下所示 -
// our wrapper function (required by grunt and its plugins) // all configuration goes inside this function module.exports = function(grunt) { // CONFIGURE GRUNT grunt.initConfig({ // get the configuration info from package.json file // this way we can use things like name and version (pkg.name) pkg: grunt.file.readJSON('package.json'), // all of our configuration goes here }); // Load the plugin that provides the "uglify" task grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s) grunt.registerTask('default', ['uglify']); };
包装函数
在上面的代码中,module.exports是一个包装函数,整个配置都在该函数内。它是一种向应用程序的其余部分显示配置的方式。
module.exports = function(grunt) { //do grunt-related things here }
项目和任务配置
Grunt 配置准备就绪后,您就可以配置 Grunt 任务。项目配置可以写在grunt.initConfig()部分。在grunt.initConfig()函数中,从 package.json 文件中获取配置信息并将其保存到pkg中。您可以使用pkg.name调用您的项目名称,并使用pkg.version调用版本。
加载 Grunt 插件和任务
使用grunt.loadNpmTasks方法从指定插件加载任务。您可以使用npm在本地安装插件,并且它必须相对于 Gruntfile。您可以使用简单的命令加载插件,如下所示 -
grunt.task.loadNpmTasks(pluginName)
自定义任务
当您通过命令行运行 Grunt 时,Grunt 将查找默认任务。在上面的代码中,我们使用了一个名为uglify的任务,它可以使用grunt命令运行。这与显式运行grunt uglify命令相同,您可以指定数组中的任务数量。
grunt.registerTask('default', ['uglify']);
Grunt - 配置任务
您可以在Gruntfile.js 文件中为 Grunt 定义特定于项目的配置数据。
Grunt配置
可以使用grunt.initConfig()方法在 Gruntfile 中初始化任务配置数据。在grunt.initConfig()函数中,从 package.json 文件中获取配置信息。配置将包含名为属性的任务和任何任意数据。
grunt.initConfig({ jshint: { // configuration for jshint task }, cssmin: { // configuration for cssmin task }, // Arbitrary non-task-specific properties my_files: ['dir1/*.js', 'dir2/*.js'], });
任务配置和目标
当您运行任务时,Grunt 会在任务命名的属性下查找配置。我们将定义具有多种配置和目标选项的任务,如下所示 -
grunt.initConfig({ jshint: { myfile1: { // configuration for "myfile1" target options }, myfile2: { // configuration for "myfile2" target options }, }, cssmin: { myfile3: { // configuration for "myfile3" target options }, }, });
这里,jshint任务有myfile1和myfile2目标,cssmin任务有myfile3目标。当您运行grunt jshint时,它将迭代任务和目标以处理指定目标的配置。
选项
在任务配置中定义选项属性,该属性将覆盖任务默认值。每个目标都包含覆盖任务级选项的选项属性。它将具有以下格式 -
grunt.initConfig({ jshint: { options: { // task-level options that overrides task defaults }, myfile: { options: { // "myfile" target options overrides task defaults }, }, myfile1: { // there is no option, target will use task-level options }, }, });
文件
Grunt 提供了一些用于指定任务应操作哪些文件的想法,并使用不同的方式来指定src-dest文件映射。以下是src和dest映射支持的一些附加属性-
filter - 它是一个指定匹配的src文件路径并返回 true 或 false 值的函数。
nonull - 当设置为 true 时,它定义非匹配模式。
点- 它匹配以句点或其他方式开头的文件名。
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 file,其值为src file。
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'], }, });
自定义过滤功能
您可以使用过滤器属性来帮助获取目标文件的详细信息。以下格式仅在与实际文件匹配时才清除文件。
grunt.initConfig({ clean: { myfile:{ src: ['temp/**/*'], filter: 'isFile', }, }, });
通配模式
通配符意味着扩展文件名。Grunt 通过使用内置的 node-glob和minimatch 库来支持通配。通配模式包括以下几点 -
- *匹配任意数量的字符,但不匹配/。
- ?匹配单个字符,但不匹配/。
- **匹配多个字符,包括/。
- {}指定逗号分隔的“或”表达式列表。
- !将否定开头的模式匹配。
例如 -
{src: 'myfile/file1.js', dest: ...} // it specifies the single file {src: 'myfile/*.js', dest: ...} //it matches all the files ending wth .js {src: 'myfile/{file1,file2}*.js', dest: ...} //defines the single node glob pattern {src: ['myfile/*.js', '!myfile/file1.js'], dest: ...} // all files will display in alpha // order except for file1.js
动态构建文件对象
当您处理单个文件时,您可以使用其他属性来动态构建文件列表。当您将Expand属性设置为 true 时,它将启用以下一些属性 -
cwd将所有src匹配到该路径。
src匹配要匹配的模式,相对于cwd。
dest属性指定目标路径前缀。
ext将使用目标路径中生成的值替换现有扩展。
extDot表示表示扩展名的句点所在的位置。它使用第一个句点或最后一个句点;默认情况下,它设置为第一个周期
flatten会从目标路径中删除所有路径部分。
重命名指定包含新目标和文件名的字符串。
重命名属性
它是一个独特的 JavaScript 函数,它返回一个字符串,并且您不能使用字符串值进行重命名。在以下示例中,复制任务将创建 README.md 的备份。
grunt.initConfig({ copy: { backup: { files: [{ expand: true, src: ['docs/README.md'], // creating a backup of README.md rename: function () { // specifies the rename function return 'docs/BACKUP.txt'; // returns a string with the complete destination } }] } } });
模板
您可以使用<% %>分隔符指定模板。从配置中读取它们时,它们将自动扩展。它包括两种类型的属性 -
<%= prop.subprop %>属性用于扩展配置中prop.subprop的值,可以引用字符串值、数组和其他对象。
<% %>属性执行用于控制流或循环的内联 JavaScript 代码。
例如 -
grunt.initConfig({ concat: { myfile: { options: { banner: '/* <%= val %> */\n', }, src: ['<%= myval %>', 'file3/*.js'], dest: 'build/<%= file3 %>.js', }, }, // properties used in task configuration templates 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") %> */\n' }, 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-手表
安装上述所有插件并按照下面给出的步骤创建一个简单的Gruntfile.js -
步骤 1 - 您需要创建一个包装函数,它封装 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: { // define a string to insert between files in the concatenated output separator: ';' }, dist: { // files needs to be concatenated src: ['src/**/*.js'], // location of the concatenated output JS file dest: 'dist/<%= pkg.name %>.js' } }
第 5 步- 现在,让我们创建另一个名为uglify的任务来缩小 JavaScript。
uglify: { options: { // banner will be inserted at the top of the output which displays the date and time banner: '/*! <%= pkg.name %> <%= grunt.template.today() %> */\n' }, dist: { files: { 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] } } }
上述任务在dist / 文件夹中创建一个文件,其中包含缩小的 .js 文件。< %= concat.dist.dest %>将指示uglify缩小 concat 任务生成的文件。
步骤 6 - 让我们通过创建jshint任务来配置 JSHint 插件。
jshint: { // define the files to lint files: ['Gruntfile.js', 'src/**/*.js'], // configure JSHint options: { // more options here if you want to override JSHint defaults globals: { jQuery: true, } } }
上面的jshint任务接受一个文件数组,然后接受一个选项对象。上述任务将查找Gruntfile.js和src/**/*.js文件中的任何编码违规。
步骤 7 - 接下来,我们有监视任务,它查找任何指定文件中的更改并运行您指定的任务。
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 - 最后,我们必须定义默认任务。
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
只需在命令行中键入grunt命令即可运行默认任务。
这是完整的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() %> */\n' }, dist: { files: { 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] } } }, jshint: { // define the files to lint files: ['Gruntfile.js', 'src/**/*.js'], // configure JSHint options: { // more options here if you want to override JSHint defaults 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任务定义一个任务列表并将任务名称指定为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 将在配置对象中搜索具有新任务名称的属性。
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 totutorialspoint。当 Grunt 作为grunt log运行时,它将记录foo: 1,2,3然后bar: Welcome totutorialspoint然后 sap: true。
基本任务
每当您运行基本任务时,Grunt 都不会搜索配置或环境。相反,它运行指定的任务函数,将指定的任何冒号分隔的参数传递为函数参数。
grunt.registerTask(taskName, [description, ] taskFunction)
在以下示例中,任务记录foo,测试 123是否通过grunt foo:testing:123命令执行 Grunt 。每当任务在没有参数的情况下运行时,如grunt foo,该任务将记录 foo,没有 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() { // Enqueue bar and baz tasks, to run after foo completes, in-order. grunt.task.run('bar', 'baz'); // Or: grunt.task.run(['bar', 'baz']); });
您还可以创建异步任务,如下所示 -
grunt.registerTask('asyncfoo', 'My "asyncfoo" task.', function() { // Force task into async mode and grab a handle to the done() function. var done = this.async(); // Run some sync stuff. grunt.log.writeln('Processing your task..'); // Run some async stuff. 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.'); } // If this task had errors then fail by returning 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() { // Fail task if foo task failed or never ran. grunt.task.requires('foo'); // This code executes if the foo task executed successfully. grunt.log.writeln('Hello, World.. Welcome to Tutorialspoint!..'); }); // Usage: // grunt foo bar doesn't log, because foo failed to execute. // **Note: This is an example of space-separated sequential commands, // (similar to executing two lines of code: `grunt foo` then `grunt bar`) // grunt bar doesn't log, because foo never ran.
只要找不到所需的配置属性,任务甚至可能失败。
grunt.registerTask('foo', 'My task "foo" .', function() { // Fail task if meta.name config properties is missing // Format 1: String grunt.config.requires('meta.name'); // or Format 2: Array grunt.config.requires(['meta', 'name']); // Log... conditionally. grunt.log.writeln('This only log if meta.name is defined in the config.'); });
任务可以访问配置属性,如下所示 -
grunt.registerTask('foo', 'My task "foo" .', function() { // Log the value of the property. Returns null if the property is undefined. grunt.log.writeln('The meta.name property is: ' + grunt.config('meta.name')); // Also logs the value of the property. Returns null if the property is undefined. grunt.log.writeln('The meta.name property is: ' + grunt.config(['meta', 'name'])); });