Javascript模組化開發2——Gruntfile.js詳解
一、grunt模組簡介
grunt外掛,是一種npm環境下的自動化工具。對於需要反覆重複的任務,例如壓縮、編譯、單元測試、linting等,自動化工具可以減輕你的勞動,簡化你的工作。grunt模組根據Gruntfile.js檔案中的配置進行任務。
如果在package.json中定義如下命令:
"scripts": {
"build": "npm install && grunt"
}
因為執行npm run build會先安裝devDependencies中定義的一些模組,則執行npm run build這個命令相當於做如下操作:
- npm install grunt-cli -g
- npm install
- grunt
二、gruntfile.js的結構:
- "wrapper" 函式
- 專案和任務配置
- 載入 grunt 外掛和任務
- 自定義任務
三、"wrapper" 函式
每一份 Gruntfile.js(和grunt外掛)都遵循同樣的格式,你所書寫的Grunt程式碼必須放在此函式內:
module.exports = function(grunt){
//do grunt-related things in here
}
四、專案和任務配置
大部分的Grunt任務都依賴某些配置資料,我們通過grunt.initConfig 方法來配置Grunt任務的引數。
grunt.initConfig 方法的引數是一個JSON物件,你可以在這個配置物件中儲存任意的資料。此外,由於這本身就是JavaScript,你還可以在這裡使用任意的有效的JS程式碼。甚至你可以用<% %>模板字串來引用已經配置過的屬性,例如:
// 專案和任務配置
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'), //獲取 package.json 中的元資料(js程式碼)
proj:{
name:'hello',
description:'a hello demo'
},
hello: {
options: {
name: '<%= proj.name %>' //用<% %>模板字串匹配hello
},
srcs: ['1.txt', '2.txt']
}
});
在grunt.initConfig 方法中配置的屬性,在任務模組中,可用grunt.config方法進行訪問,例如:
grunt.config("proj.name");
另外,grunt任務模組會自動根據任務名來提取配置物件中和任務名對應的屬性,比如定義任務hello,則在配置物件對應的屬性"hello"中配置任務執行函式中所需用到的配置和資料。
五、載入grunt外掛任務
為了減少重複勞動,我們可以載入已有的外掛任務。
1.載入自己私有的grunt外掛
可將自己定義的一些task指令碼放在同一個目錄下,通過grunt.loadTasks方法從指定目錄載入該目錄下所有的grunt任務指令碼。
2.載入在npm中釋出的grunt外掛
像 grunt-contrib-copy和grunt-contrib-uglify這些常用的任務都已經以grunt外掛的形式被開發出來了,且被髮布在npm公開庫中,只要在 package.json 檔案中將需要使用的外掛列在dependency中,並通過npm install安裝之後,就可以直接載入該任務。
// 載入能夠提供"copy"任務的外掛。
grunt.loadNpmTasks('grunt-contrib-copy');
3.直接載入所有以"grunt-"打頭的外掛
npm上有個load-grunt-tasks外掛可以用來載入dependency列表中所有以"grunt-"打頭的外掛。
將需要使用的"grunt-"打頭的外掛列在dependency中,然後在Gruntfile.js中進行呼叫。
//Load grunt tasks from NPM packages
load-grunt-tasks
六、自定義任務
1.直接定義任務的行為
grunt.registerTask('hello', 'Show some msg', function() {
console.log(this.options().name); //輸出hello
});
2.定義為任務列表
可以將一個任務定義為一系列任務的組合,這一系列任務將按照順序執行。
grunt.registerTask('dothings', 'copy and Show some msg', ['copy','hello']);
3.定義預設任務
通過定義 default 任務,可以讓Grunt預設執行一個或多個任務。執行 grunt 命令時如果不指定一個任務的話,將會執行預設任務。如進行下面定義的話執行grunt 相當於執行grunt hello。
grunt.registerTask('default', ['hello']);
4.定義複合任務
registerMultiTask方法可以定義一個複合任務,複合任務將會對grunt.initConfig 方法中配置的相應屬性中除了options外定義的屬性依次作為target:data對進行處理。
module.exports = function(grunt) {
grunt.initConfig({
Log: {
options: {
sep: ';'
},
srcs: ['1.txt', '2.txt'],
dests: ['d1.txt', 'd2.txt']
}
});
grunt.registerMultiTask("Log", function() {
var options = this.options({ sep: '&' });
console.log(this.target);
console.log(this.data.join(options.sep));
});
};
執行grunt Log將會輸出:
Running "Log:srcs" (Log) task
srcs
1.txt;2.txt
Running "Log:dests" (Log) task
dests
d1.txt;d2.txt
定義任務行為Tips
1.任務內部可以執行其他的任務。
grunt.registerTask('mytask', function() {
grunt.task.run('task1', 'task2');
// Or:
grunt.task.run(['task1', 'task2']);
});
2.定義非同步任務
grunt.registerTask('mytask', function() {
var done = this.async();
//do something
done();
});
3.當任務失敗時,所有後續任務都將終止
在任務中,當執行失敗,可以return false來表明當前任務執行失敗,一般,多個任務按順序執行,如果有任務失敗時,所有後續任務都將終止。可以通過在命令列後加上--force來使有任務失敗時,後續任務能繼續進行。
4.任務中檢查前置任務狀態
有些任務可以依賴於其他任務的成功執行。通過grunt.task.requires方法來檢查其前置任務是否已經執行,並且沒有失敗。
5.任務中檢查配置屬性
可以用方法grunt.task.requiresConfig指定一個或者多個字串或者陣列的配置屬性為必需的。如果一個或多個必需的配置屬性缺失,就通知系統當前任務失敗