- Grunt 教程
- Grunt - 首頁
- Grunt - 概述
- Grunt - 特性
- Grunt - 安裝
- Grunt - 入門
- Grunt - 配置任務
- Grunt - 示例檔案
- Grunt - 建立任務
- Grunt 有用資源
- Grunt - 快速指南
- Grunt - 有用資源
- Grunt - 討論
Grunt - 快速指南
Grunt - 概述
什麼是 Grunt?
Grunt 是一個 JavaScript 任務執行器,可以用作 JavaScript 物件的命令列工具。它是一個構建在 NodeJS 之上的任務管理器。
為什麼要使用 Grunt?
Grunt 可以非常輕鬆地執行重複性任務,例如編譯、單元測試、壓縮檔案、執行測試等。
Grunt 包含內建任務,可以擴充套件外掛和指令碼的功能。
Grunt 的生態系統非常龐大;您可以用很少的精力自動化任何操作。
歷史
GruntJS 的第一行原始碼於 2011 年新增。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.com.tw/en/,您將看到如下所示的螢幕:
下載壓縮檔案的最新功能版本。
步驟 2 - 接下來,執行安裝程式以在您的計算機上安裝NodeJs。
步驟 3 - 接下來,您需要設定環境變數。
路徑使用者變數
- 右鍵單擊我的電腦。
- 選擇屬性。
- 接下來,選擇高階選項卡,然後單擊環境變數。
在環境變數視窗下,雙擊PATH,如螢幕所示。
您將獲得一個編輯使用者變數視窗,如所示。在變數值欄位中新增 NodeJs 資料夾路徑,如C:\Program Files\nodejs\node_modules\npm。如果已為其他檔案設定了路徑,則需要在其後新增分號(;),然後新增 NodeJs 路徑,如下所示:
最後,單擊確定按鈕。
系統變數
在系統變數下,雙擊Path,如以下螢幕所示。
您將獲得一個編輯系統變數視窗,如所示。在變數值欄位中新增 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。
package.json
package.json檔案放置在專案的根目錄中,位於Gruntfile旁邊。package.json用於在您在與 package.json 相同的資料夾中執行命令npm install時正確執行每個列出的依賴項。
可以透過在命令提示符中鍵入以下命令來建立基本的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檔案如下所示:
// 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 安裝
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檔案如下所示:
// 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 將查詢default任務。在上面的程式碼中,我們使用了一個名為uglify的任務,它可以使用grunt命令執行。這與顯式執行grunt uglify命令相同,您可以在陣列中指定任務數量。
grunt.registerTask('default', ['uglify']);
Grunt - 配置任務
您可以在Gruntfile.js 檔案中定義專案特定的配置資料。
Grunt 配置
可以透過使用grunt.initConfig()方法在 Gruntfile 中初始化任務配置資料。在grunt.initConfig()函式內部,獲取來自 package.json 檔案的配置資訊。配置將包含一個名為properties的任務和任意資料。
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 時,它將遍歷任務和目標以處理指定目標的配置。
選項
在任務配置內定義 options 屬性,該屬性會覆蓋任務預設值。每個目標都包含 options 屬性,該屬性會覆蓋任務級別的選項。它將具有以下格式:
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 時,它定義不匹配的模式。
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: ...} // 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 將用在 dest 路徑中生成的 value 替換現有副檔名。
extDot 指示指示副檔名的句點所在位置。它使用第一個句點或最後一個句點;預設情況下,它設定為第一個句點。
flatten 從 dest 路徑中刪除所有路徑部分。
rename 指定包含新目標和檔名的字串。
Rename 屬性
它是一個唯一的 JavaScript 函式,返回一個字串,您不能對 rename 使用字串值。在以下示例中,copy 任務將建立 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-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: {
// 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 任務,它查詢任何指定檔案的更改並執行您指定的任務。
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() %> */\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 您希望它執行的操作。如果您指定了 default 任務,則它將預設執行。
別名任務
每當指定任務列表時,一個或多個其他任務都可以透過新任務進行別名化。執行別名將依次執行 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 配置中搜索同名屬性。這些任務可以有多個配置,這些配置將使用任意命名的 targets 定義。
當您同時指定任務和目標時,只會處理指定的 target 配置。
grunt concat:foo
上述命令將只執行目標 foo。
當您只指定任務時,將處理所有目標。
grunt concat
上述命令將遍歷 concat 任務的所有目標。
當您使用 grunt.task.renameTask 重新命名任務時,Grunt 會在 config 物件中搜索具有 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 不會搜尋配置或環境。而是執行指定的 task 函式,並將作為函式引數指定的任何冒號分隔的引數傳遞進去。
grunt.registerTask(taskName, [description, ] taskFunction)
在以下示例中,如果 Grunt 透過 grunt foo:testing:123 命令執行,則任務將記錄 foo, testing 123。每當任務在沒有引數的情況下作為 grunt foo 執行時,任務將 log 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() {
// 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']));
});