快速入門
Grunt和 Grunt 插件是通過 npm 安裝并管理的,npm是 Node.js 的包管理器。
在安裝 Grunt 前,請確保當(dāng)前環(huán)境中所安裝的 npm 已經(jīng)是最新版本,執(zhí)行npm update -g npm指令進(jìn)行升級(在某些系統(tǒng)中可能需要 sudo指令)。
安裝CLI
需要先將Grunt命令行(CLI)安裝到全局環(huán)境中。
npm install -g grunt-cli
上述命令執(zhí)行完后,grunt 命令就被加入到你的系統(tǒng)路徑中了,以后就可以在任何目錄下執(zhí)行此命令了。
注意,安裝grunt-cli并不等于安裝了 Grunt!Grunt CLI的任務(wù)很簡單:調(diào)用與Gruntfile在同一目錄中的 Grunt。這樣帶來的好處是,允許你在同一個系統(tǒng)上同時安裝多個版本的 Grunt。這樣就能讓多個版本的 Grunt 同時安裝在同一臺機(jī)器上。
每次運(yùn)行grunt 時,他就利用node提供的require()系統(tǒng)查找本地安裝的 Grunt。正是由于這一機(jī)制,你可以在項(xiàng)目的任意子目錄中運(yùn)行grunt。如果找到一份本地安裝的 Grunt,CLI就將其加載,并傳遞Gruntfile中的配置信息,然后執(zhí)行你所指定的任務(wù)。
準(zhǔn)備一個新的Grunt項(xiàng)目
一般需要在你的項(xiàng)目中添加兩份文件:package.json 和 Gruntfile。
package.json: 此文件被npm用于存儲項(xiàng)目的元數(shù)據(jù),以便將此項(xiàng)目發(fā)布為npm模塊。你可以在此文件中列出項(xiàng)目依賴的grunt和Grunt插件,放置于devDependencies配置段內(nèi)。
Gruntfile: 此文件被命名為 Gruntfile.js 或 Gruntfile.coffee,用來配置或定義任務(wù)(task)并加載Grunt插件的。 此文檔中提到的 Gruntfile 其實(shí)說的是一個文件,文件名是 Gruntfile.js 或 Gruntfile.coffee。
把package.json和Gruntfile文件放在項(xiàng)目的根目錄中.npm init命令會創(chuàng)建一個基本的package.json文件。
安裝Grunt 和 grunt插件
通過npm install <module> --save-dev命令,不光安裝了<module>
,還會自動將其添加到devDependencies 配置段中,
例如,下面這條命令將安裝Grunt最新版本到項(xiàng)目目錄中,并將其添加到devDependencies內(nèi):
npm install grunt --save-dev
同樣,grunt插件和其它node模塊都可以按相同的方式安裝。下面展示的實(shí)例就是安裝 JSHint 任務(wù)模塊:
npm install grunt-contrib-jshint --save-dev
在 Grunt 插件 頁面可以看到當(dāng)前可用的 Grunt 插件,他們可以直接在項(xiàng)目中安裝并使用。
安裝插件之后,請務(wù)必確保將更新之后的 package.json文件提交到項(xiàng)目倉庫中。
Gruntfile
Gruntfile.js 或 Gruntfile.coffee 文件是有效的 JavaScript 或 CoffeeScript 文件,應(yīng)當(dāng)放在你的項(xiàng)目根目錄中,和package.json文件在同一目錄層級,并和項(xiàng)目源碼一起加入源碼管理器。
Gruntfile由以下幾部分構(gòu)成:
- "wrapper" 函數(shù)
- 項(xiàng)目與任務(wù)配置
- 加載grunt插件和任務(wù)
- 自定義任務(wù)
在下面列出的這個 Gruntfile 中,package.json文件中的項(xiàng)目元數(shù)據(jù)(metadata)被導(dǎo)入到 Grunt 配置中, grunt-contrib-uglify 插件中的uglify 任務(wù)(task)被配置為壓縮(minify)源碼文件并依據(jù)上述元數(shù)據(jù)動態(tài)生成一個文件頭注釋。當(dāng)在命令行中執(zhí)行 grunt 命令時,uglify 任務(wù)將被默認(rèn)執(zhí)行。
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');
// 默認(rèn)被執(zhí)行的任務(wù)列表。
grunt.registerTask('default', ['uglify']);
};
前面已經(jīng)展示了整個 Gruntfile,接下來將詳細(xì)解釋其中的每一部分。
"wrapper" 函數(shù)
每一份 Gruntfile (和grunt插件)都遵循同樣的格式,你所書寫的Grunt代碼必須放在此函數(shù)內(nèi):
module.exports = function(grunt) {
// Do grunt-related things in here
};
項(xiàng)目和任務(wù)配置
大部分的Grunt任務(wù)都依賴某些配置數(shù)據(jù),這些數(shù)據(jù)被定義在一個object內(nèi),并傳遞給grunt.initConfig 方法。
在下面的案例中,grunt.file.readJSON('package.json') 將存儲在package.json文件中的JSON元數(shù)據(jù)引入到grunt config中。由于<% %>模板字符串可以引用任意的配置屬性,因此可以通過這種方式來指定諸如文件路徑和文件列表類型的配置數(shù)據(jù),從而減少一些重復(fù)的工作。
你可以在這個配置對象中(傳遞給initConfig()方法的對象)存儲任意的數(shù)據(jù),只要它不與你任務(wù)配置所需的屬性沖突,否則會被忽略。此外,由于這本身就是JavaScript,你不僅限于使用JSON;你可以在這里使用任意的有效的JS代碼。如果有必要,你甚至可以以編程的方式生成配置。
與大多數(shù)task一樣,grunt-contrib-uglify 插件中的uglify 任務(wù)要求它的配置被指定在一個同名屬性中。在這里有一個例子, 我們指定了一個banner選項(xiàng)(用于在文件頂部生成一個注釋),緊接著是一個單一的名為build的uglify目標(biāo),用于將一個js文件壓縮為一個目標(biāo)文件。
// 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'
}
}
});
加載 Grunt 插件和任務(wù)
像 concatenation、[minification]、grunt-contrib-uglify 和 linting這些常用的任務(wù)(task)都已經(jīng)以grunt插件的形式被開發(fā)出來了。只要在 package.json 文件中被列為dependency(依賴)的包,并通過npm install安裝之后,都可以在Gruntfile中以簡單命令的形式使用:
// 加載能夠提供"uglify"任務(wù)的插件。
grunt.loadNpmTasks('grunt-contrib-uglify');
注意: grunt --help 命令將列出所有可用的任務(wù)。
自定義任務(wù)
通過定義 default 任務(wù),可以讓Grunt默認(rèn)執(zhí)行一個或多個任務(wù)。在下面的這個案例中,執(zhí)行 grunt 命令時如果不指定一個任務(wù)的話,將會執(zhí)行uglify任務(wù)。這和執(zhí)行grunt uglify 或者 grunt default的效果一樣。default任務(wù)列表數(shù)組中可以指定任意數(shù)目的任務(wù)(可以帶參數(shù))。
// Default task(s).
grunt.registerTask('default', ['uglify']);
如果Grunt插件中的任務(wù)(task)不能滿足你的項(xiàng)目需求,你還可以在Gruntfile中自定義任務(wù)(task)。例如,在下面的 Gruntfile 中自定義了一個default 任務(wù),并且他甚至不依賴任務(wù)配置:
module.exports = function(grunt) {
// A very basic default task.
grunt.registerTask('default', 'Log some stuff.', function() {
grunt.log.write('Logging some stuff...').ok();
});
};
特定于項(xiàng)目的任務(wù)不必在 Gruntfile中定義。他們可以定義在外部.js文件中,并通過grunt.loadTasks方法加載。