Grunt和 Grunt 插件是通過 npm 安裝并管理的,npm是 Node.js 的包管理器。
Grunt 0.4.x 必須配合Node.js >= 0.8.0版本使用。;奇數(shù)版本號的 Node.js 被認為是不穩(wěn)定的開發(fā)版。
在安裝 Grunt 前,請確保當前環(huán)境中所安裝的 npm 已經(jīng)是最新版本,執(zhí)行 npm update -g npm 指令進行升級(在某些系統(tǒng)中可能需要 sudo 指令)。
如果你已經(jīng)安裝了 Grunt,現(xiàn)在需要參考一些文檔手冊,那就請看一看 Gruntfile 實例 和如何 配置任務(wù)吧。
還在使用 Grunt 0.3 版本嗎?請查看 Grunt 0.3 注意事項
在繼續(xù)學習前,你需要先將Grunt命令行(CLI)安裝到全局環(huán)境中。安裝時可能需要使用sudo(針對OSX、*nix、BSD等系統(tǒng)中)權(quán)限或者作為管理員(對于Windows環(huán)境)來執(zhí)行以下命令。
npm install -g grunt-cli
上述命令執(zhí)行完后,grunt 命令就被加入到你的系統(tǒng)路徑中了,以后就可以在任何目錄下執(zhí)行此命令了。
注意,安裝grunt-cli并不等于安裝了 Grunt!Grunt CLI的任務(wù)很簡單:調(diào)用與Gruntfile在同一目錄中 Grunt。這樣帶來的好處是,允許你在同一個系統(tǒng)上同時安裝多個版本的 Grunt。
這樣就能讓多個版本的 Grunt 同時安裝在同一臺機器上。
每次運行g(shù)runt 時,他就利用node提供的require()系統(tǒng)查找本地安裝的 Grunt。正是由于這一機制,你可以在項目的任意子目錄中運行g(shù)runt 。
如果找到一份本地安裝的 Grunt,CLI就將其加載,并傳遞Gruntfile中的配置信息,然后執(zhí)行你所指定的任務(wù)。為了更好的理解 Grunt CLI的執(zhí)行原理,請閱讀源碼。
假定Grunt CLI已經(jīng)正確安裝,并且已經(jīng)有一份配置好package.json 和 Gruntfile 文件的項目了,接下來就很容易拿Grunt練手了:
OK,就是這么簡單。還可以通過grunt --help 命令列出所有已安裝的Grunt任務(wù)(task),但是一般更建議去查看項目的文檔以獲取幫助信息。
一般需要在你的項目中添加兩份文件:package.json 和 Gruntfile。
package.json: 此文件被npm用于存儲項目的元數(shù)據(jù),以便將此項目發(fā)布為npm模塊。你可以在此文件中列出項目依賴的grunt和Grunt插件,放置于devDependencies配置段內(nèi)。
Gruntfile: 此文件被命名為 Gruntfile.js 或 Gruntfile.coffee,用來配置或定義任務(wù)(task)并加載Grunt插件的。 此文檔中提到的 Gruntfile 其實說的是一個文件,文件名是 Gruntfile.js 或Gruntfile.coffee。
package.json應(yīng)當放置于項目的根目錄中,與Gruntfile在同一目錄中,并且應(yīng)該與項目的源代碼一起被提交。在上述目錄(package.json所在目錄)中運行npm install將依據(jù)package.json文件中所列出的每個依賴來自動安裝適當版本的依賴。
下面列出了幾種為你的項目創(chuàng)建package.json文件的方式:
{ "name": "my-project-name", "version": "0.1.0", "devDependencies": { "grunt": "~0.4.5", "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-nodeunit": "~0.4.1", "grunt-contrib-uglify": "~0.5.0" } }
向已經(jīng)存在的package.json 文件中添加Grunt和grunt插件的最簡單方式是通過npm install <module> --save-dev命令。此命令不光安裝了<module>,還會自動將其添加到devDependencies 配置段中,遵循tilde version range格式。
例如,下面這條命令將安裝Grunt最新版本到項目目錄中,并將其添加到devDependencies內(nèi):
npm install grunt --save-dev
同樣,grunt插件和其它node模塊都可以按相同的方式安裝。下面展示的實例就是安裝 JSHint 任務(wù)模塊:
npm install grunt-contrib-jshint --save-dev
在 Grunt 插件 頁面可以看到當前可用的 Grunt 插件,他們可以直接在項目中安裝并使用。
安裝插件之后,請務(wù)必確保將更新之后的 package.json 文件提交到項目倉庫中。
Gruntfile.js 或 Gruntfile.coffee 文件是有效的 JavaScript 或 CoffeeScript 文件,應(yīng)當放在你的項目根目錄中,和package.json文件在同一目錄層級,并和項目源碼一起加入源碼管理器。
Gruntfile由以下幾部分構(gòu)成:
在下面列出的這個 Gruntfile 中,package.json文件中的項目元數(shù)據(jù)(metadata)被導入到 Grunt 配置中, grunt-contrib-uglify 插件中的uglify 任務(wù)(task)被配置為壓縮(minify)源碼文件并依據(jù)上述元數(shù)據(jù)動態(tài)生成一個文件頭注釋。當在命令行中執(zhí)行 grunt 命令時,uglify 任務(wù)將被默認執(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'); // 默認被執(zhí)行的任務(wù)列表。 grunt.registerTask('default', ['uglify']); };
前面已經(jīng)向你展示了整個 Gruntfile,接下來將詳細解釋其中的每一部分。
每一份 Gruntfile (和grunt插件)都遵循同樣的格式,你所書寫的Grunt代碼必須放在此函數(shù)內(nèi):
module.exports = function(grunt) { // Do grunt-related things in here };
大部分的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ù),從而減少一些重復的工作。
你可以在這個配置對象中(傳遞給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' } } });
像 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ù)。
通過定義 default 任務(wù),可以讓Grunt默認執(zhí)行一個或多個任務(wù)。在下面的這個案例中,執(zhí)行 grunt 命令時如果不指定一個任務(wù)的話,將會執(zhí)行uglify任務(wù)。這和執(zhí)行g(shù)runt uglify 或者 grunt default的效果一樣。default任務(wù)列表數(shù)組中可以指定任意數(shù)目的任務(wù)(可以帶參數(shù))。
// Default task(s). grunt.registerTask('default', ['uglify']);
如果Grunt插件中的任務(wù)(task)不能滿足你的項目需求,你還可以在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(); }); };
特定于項目的任務(wù)不必在 Gruntfile 中定義。他們可以定義在外部.js 文件中,并通過grunt.loadTasks方法加載。
更多建議: