Grunt入門(一)
什么是grunt
Grunt
就和photoshop
里面的插件一樣纫普,它能夠幫我們自動完成一些反復重復的任務(wù)
ps插件里默刚,我們經(jīng)常會用動自動切圖媚创,自動導出切片這樣的工具丹允。grunt
里面蹄殃,就可以使用自動編譯LESS
携茂、壓縮CSS
、JS
這樣的工具诅岩。
Grunt
是一個平臺讳苦,沒有插件,Grunt
什么事也不能做吩谦。它是提供了一個標準鸳谜,任何插件都要去遵守的一個機制和規(guī)則。就和USB接口一樣式廷,接在USB插口的咐扭,有可能是U盤,攝像頭這些完成不同功能的外設(shè)滑废。
為什么要用Grunt
Grunt
有一個龐大的生態(tài)圈蝗肪, 里面有各種各樣現(xiàn)成的插件,可以滿足大部分的日常需要蠕趁。無需額外開發(fā)薛闪。
快速安裝
- 安裝
Node.js
- 使用
npm
安裝Grunt
npm install -g grunt-cli
Gruntfile.js與package.json
每一個Grunt
項目都會帶上這兩個文件,接下來分別講解這兩個文件的用途俺陋。
package.json
npm
命令運行時會讀取當前目錄的 package.json
文件和解釋這個文件豁延,這個文件基于Packages/1.1
規(guī)范昙篙。
在這個文件里你可以定義你的應用名稱( name )、應用描述( description )诱咏、關(guān)鍵字( keywords )苔可、版本號( version )、應用的配置項( config )胰苏、主頁( homepage )硕蛹、作者( author )醇疼、資源倉庫地址( repository )硕并、bug的提交地址( bugs ),授權(quán)方式( licenses )秧荆、目錄( directories )倔毙、應用入口文件( main )、命令行文件( bin )乙濒、應用依賴模塊( dependencies )陕赃、開發(fā)環(huán)境依賴模塊( devDependencies )、運行引擎( engines )和腳本( scripts )等颁股。
下面是一份完整的package.json
:
{
"name": "test",
"version": "0.1.0",
"description": "A testing package",
"author": "A messed author <messed@example.com>",
"dependencies": {
"express": "1.x.x",
"ejs": "0.4.2",
"redis": ">= 0.6.7"
},
"devDependencies": {
"vows": "0.5.x"
},
"main": "index",
"bin": {
"test": "./bin/test.js"
},
"scripts": {
"start": "node server.js",
"test": "vows test/*.js",
"preinstall": "./configure",
"install": "make && make install"
},
"engines": {
"node": "0.4.x"
}
}
當在項目的根目錄中運行npm install
時么库,npm會自動去安裝dependencies中定義的依賴包,在項目的根目錄中生成一個node_modules的文件夾甘有,這個項目所需要的node庫就安裝在這個目錄下诉儒。
其余關(guān)于package.json的含義暫時不說。
Gruntfile.js
這個文件與package.json一樣亏掀,放在文件的根目錄下忱反。
一個Gruntfile.js包含以下幾個部分:
- "wrapper" 函數(shù)
- 項目與任務(wù)配置
- 加載grunt插件和任務(wù)
- 自定義任務(wù)
一份完整的Gruntfile文件
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
}
});
// 加載包含 "uglify" 任務(wù)的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');
// 默認被執(zhí)行的任務(wù)列表滤愕。
grunt.registerTask('default', ['uglify']);
};
"wrapper" 函數(shù)
每一份 Gruntfile (和grunt插件)都遵循同樣的格式温算,寫的Grunt代碼必須放在此函數(shù)內(nèi):
module.exports = function(grunt) {
// Do grunt-related things in here
};
項目與任務(wù)配置
大部分的Grunt任務(wù)都依賴某些配置數(shù)據(jù)項,這些數(shù)據(jù)被定義在一個Object內(nèi)间影,作為參數(shù)傳遞給grunt.initConfig()
方法注竿。
在下面的案例中,
grunt.file.readJSON('package.json')
將存儲在package.json
文件中的JSON元數(shù)據(jù)引入到grunt config
中魂贬。 由于<% %>
模板字符串可以引用任意的配置屬性巩割,因此可以通過這種方式來指定諸如文件路徑和文件列表類型的配置數(shù)據(jù),從而減少一些重復的工作随橘。
你可以在這個配置對象中(傳遞給initConfig()
方法的對象)存儲任意的數(shù)據(jù)喂分,只要它不與你任務(wù)配置所需的屬性沖突,否則會被 忽略机蔗。此外蒲祈,由于這本身就是JavaScript
甘萧,你不僅限于使用JSON
;你可以在這里使用任意的有效的JS
代碼梆掸。如果有必要扬卷,你甚至可以以編程的方式生成配置。
與大多數(shù)task一樣酸钦,grunt-contrib-uglify
插件中的uglify
任務(wù)要求它的配置被指定在一個同名屬性中怪得。在這里有一個例子, 我們指定了一個banner選項(用于在文件頂部生成一個注釋),緊接著是一個單一的名為build
的uglify
目標卑硫,用于將一個js
文件壓縮為一個目標文件徒恋。
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
}
});
當使用其他開發(fā)者開發(fā)的一些插件的時候,一般都會有說明這個配置格式欢伏,下面是從github
中找的一個關(guān)于雪碧圖合并的插件:
// 自動雪碧圖
sprite: {
allslice: {
files: [
{
//啟用動態(tài)擴展
expand: true,
// css文件源的文件夾
cwd: 'css',
// 匹配規(guī)則
src: ['*.css'],
//導出css和sprite的路徑地址
dest: 'tmp/',
// 導出的css名
ext: '.sprite.css'
}
],
options: {
// 默認使用GM圖像處理引擎
'engine': 'gm',
// 默認使用二叉樹最優(yōu)排列算法
'algorithm': 'binary-tree',
// 給雪碧圖追加時間戳入挣,默認不追加
'imagestamp':false,
// 給樣式文件追加時間戳,默認不追加
'cssstamp':true,
// 是否以時間戳為文件名生成新的雪碧圖文件硝拧,默認不生成新文件
'newsprite':true
}
}
}
加載grunt插件和任務(wù)
插件的安裝是定義在package.json中的dependencies對象里径筏。如果我們已經(jīng)我們要在后期繼續(xù)添加插件,可以通過
npm install grunt-contrib-less --save-dev
的方式來安裝障陶。
安裝好需要的grunt插件后滋恬,就需要把插件引入到項目中。比如我們要引入剛剛安裝好的grunt-contrib-less
那我們就需要在gruntfile
中使用如下方法:
grunt.loadNpmTasks('grunt-contrib-less');
自定義任務(wù)
grunt允許開發(fā)者自定義參數(shù)來指定執(zhí)行特定的任務(wù)抱究。比如恢氯,當需要grunt-contrib-less這個插件來執(zhí)行l(wèi)ess編譯的時候,可以用grunt.registerTask()
指定一個運行參數(shù)來自定義任務(wù)媳维,如grunt.registerTask('less', ['less']);
酿雪。當執(zhí)行l(wèi)ess編譯時,只需要運行這樣的代碼就行grunt less
侄刽。grunt也提供默認的執(zhí)行方法指黎, 如果只想運行grunt
命令,不加參數(shù)就能執(zhí)行l(wèi)ess編譯的話州丹,我們也可以這樣來自定義任務(wù)grunt.registerTask('default', ['less']);
醋安。方法的第二個參數(shù)是一個數(shù)組,那就說明墓毒,一個參數(shù)是可以來執(zhí)行多個任務(wù)的吓揪。執(zhí)行的順序按照數(shù)組的順序串聯(lián)執(zhí)行。舉個例子所计,在less編譯完之后柠辞,想做一下圖片壓縮和JS壓縮吊履,那我們可以這樣做:
grunt.registerTask('publish', ['less', 'imagemin', 'uglify']);
那么問題來了菲嘴,是不是每一次新建一個項目都要去重寫這個gruntfile.js
和package.json
呢锡溯?答案肯定不是……
第二節(jié)互广,再繼續(xù)講講腳手架(自動生成工具)yo
與Grunt
的關(guān)系和使用。