1. Grunt 的介紹和使用
參考鏈接:http://www.gruntjs.net/ Grunt中文網(wǎng)
為何要用構(gòu)建工具?
一句話:自動(dòng)化。對(duì)于需要反復(fù)重復(fù)的任務(wù),例如壓縮(minification)、編譯、單元測(cè)試、linting等,自動(dòng)化工具可以減輕你的勞動(dòng),簡(jiǎn)化你的工作。當(dāng)你在 Gruntfile 文件正確配置好了任務(wù),任務(wù)運(yùn)行器就會(huì)自動(dòng)幫你或你的小組完成大部分無(wú)聊的工作。
為什么要使用Grunt?
Grunt生態(tài)系統(tǒng)非常龐大,并且一直在增長(zhǎng)。由于擁有數(shù)量龐大的插件可供選擇,因此,你可以利用Grunt自動(dòng)完成任何事,并且花費(fèi)最少的代價(jià)。如果找不到你所需要的插件,那就自己動(dòng)手創(chuàng)造一個(gè)Grunt插件,然后將其發(fā)布到npm上吧。先看看入門(mén)文檔吧。
可用的Grunt插件
你所需要的大多數(shù)task都已經(jīng)作為Grunt插件被開(kāi)發(fā)了出來(lái),并且每天都有更多的插件誕生。插件列表頁(yè)面列出了完整的清單。下面給出幾個(gè)你可能聽(tīng)說(shuō)過(guò)的插件:
- CoffeeScript 它和思想跟 Ruby 特別的像,是我們可以更簡(jiǎn)單的去寫(xiě) JS ,它使得我們整個(gè)的書(shū)寫(xiě) JS 變得十分簡(jiǎn)單
- handlebars 它是有個(gè)模板引擎
- jade 它也是有個(gè)模板引擎
- JS Hint 它是一個(gè)代碼檢查工具,他可以把我們平常團(tuán)隊(duì)規(guī)范的 JS 進(jìn)行規(guī)整,不讓每個(gè)人去隨意地書(shū)寫(xiě) JS ,它有一個(gè)完整的列表,可以根據(jù)我們整個(gè) Team 相關(guān)的需要把我們的配置寫(xiě)到它的配置文件里面,這個(gè)時(shí)候大家就都必須遵守這個(gè)配置進(jìn)行書(shū)寫(xiě)
- Less 它是一個(gè) css 預(yù)處理器,可以讓 css 像編程一樣去書(shū)寫(xiě)
- REQUIRE.JS 它是一個(gè) JS 模塊化的工具,也是一個(gè)非常偉大的庫(kù)
- Sass 它也是一個(gè) css 預(yù)處理器,跟 Less 所做的功能差不多
- Stylus 它也是一個(gè) css 預(yù)處理器,跟 Less 所做的功能差不多
2. Grunt 的安裝
參考鏈接:http://www.gruntjs.net/getting-started Grunt 快速入門(mén)
- 安裝 CLI
npm install -g grunt-cli
上述命令執(zhí)行完后,grunt 命令就被加入到你的系統(tǒng)路徑中了,以后就可以在任何目錄下執(zhí)行此命令了。
注意,安裝grunt-cli并不等于安裝了 Grunt!
Grunt CLI的任務(wù)很簡(jiǎn)單:調(diào)用與Gruntfile在同一目錄中 Grunt。這樣帶來(lái)的好處是,允許你在同一個(gè)系統(tǒng)上同時(shí)安裝多個(gè)版本的 Grunt。
這樣就能讓多個(gè)版本的 Grunt 同時(shí)安裝在同一臺(tái)機(jī)器上。
CLI 是如何工作的
每次運(yùn)行grunt時(shí),他就利用node提供的require()系統(tǒng)查找本地安裝的 Grunt。正是由于這一機(jī)制,你可以在項(xiàng)目的任意子目錄中運(yùn)行grunt。
- 在桌面新建一個(gè) grunttest 文件夾,并在 命令行中進(jìn)入該目錄下
cd Desktop
cd grunttest
- Grunt CLI 已經(jīng)正確安裝,還需要在項(xiàng)目中新建兩個(gè)文件 package.json 和 Gruntfile,這兩個(gè)是 運(yùn)行 Grunt 必須有的文件
- 項(xiàng)目初始化,生成 package.json 文件
- 在項(xiàng)目中安裝 grunt 工具
cnpm install grunt --save-dev
-
此時(shí)運(yùn)行 grunt ,命令行中會(huì)報(bào)如下錯(cuò)誤
image.png
無(wú)法找到 gruntfile ,gruntfile 是項(xiàng)目中寫(xiě)任務(wù)的文件 它可以是一個(gè)文件也可是是一個(gè)文件夾
- 在項(xiàng)目中新建一個(gè) gruntfile.js 文件
- 運(yùn)行 grunt ,命令行中會(huì)報(bào)如下錯(cuò)誤

這個(gè)是因?yàn)槲覀儾](méi)有書(shū)寫(xiě)需要執(zhí)行什么任務(wù)的代碼,現(xiàn)在安裝步驟已經(jīng)完成了
3. Grunt 的應(yīng)用
參考鏈接:http://www.gruntjs.net/configuring-tasks Grunt 配置任務(wù)
- 在之前的項(xiàng)目中新建文件 結(jié)構(gòu)如下
js -> index.js
js -> main.js
index.html
build
dest
- 編輯文件
index.js
var index = index || {};
index = {
init:function(argument) {
console.log('index init');
}
}
index.init();
main.js
function test(argument) {
this.a = 1;
};
test.prototype.method_name = function(){
console.log(this.a);
};
gruntfile.js 暫時(shí)配置了第一個(gè) uglify 壓縮任務(wù)
//不需要 require 直接以模塊的形式便可以把 grunt 引入進(jìn)來(lái)
module.exports = function(grunt) {
//grunt 初始化
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//壓縮
uglify: {
options:{
//后面的命令是 grunt 模塊自帶的命令,他創(chuàng)建了一個(gè)時(shí)間
banner:'/*! create by <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
//這個(gè)是幫我們找到靜態(tài)資源所對(duì)應(yīng)的目錄 它可以把我們的靜態(tài)資源指定 從哪來(lái) 到哪去
static_mappings:{
//files 可以支持?jǐn)?shù)組進(jìn)行批量的操作
files:[{
//從哪來(lái)
src:'js/index.js',
//到哪去
dest:'build/index.min.js'
},{
src:'js/main.js',
dest:'build/main.min.js'
}]
}
},
//合并
concat: {
},
//觀察本地文件的變化,讓他去可以工作
watch: {
}
});
//加載上面初始化時(shí)配置的插件 這些需要的包都需要在命令行中進(jìn)行安裝 --save-dev
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
//默認(rèn)被執(zhí)行的任務(wù)列表
grunt.registerTask('default',['uglify'])
}
- 安裝在 gruntfile.js 文件中所用到的三個(gè)插件
cnpm install grunt-contrib-uglify --save-dev
cnpm install grunt-contrib-concat --save-dev
cnpm install grunt-contrib-watch --save-dev
- 運(yùn)行程序
grunt,如下圖所示,執(zhí)行成功了

- 因?yàn)樯厦娴膱?zhí)行任務(wù)列表只寫(xiě)了 uglify 壓縮命令,此時(shí)去查看 build 文件夾會(huì)發(fā)現(xiàn)里面多出了 一個(gè) index.min.js 和 main.min.js 文件
index.min.js
/*! create by 2017-11-25 */
var index=index||{};(index={init:function(i){console.log("index init")}}).init();
main.min.js
/*! create by 2017-11-25 */
function test(t){this.a=1}test.prototype.method_name=function(){console.log(this.a)};
這兩個(gè)文件就是將 index.js 和 main.js 文件壓縮后得到的對(duì)應(yīng)的兩個(gè)文件
- 編輯 gruntfile.js 文件 添加
concat合并命令
//合并
concat: {
bar: {
src: ['build/*.js'],
dest: 'dest/all.min.js'
}
}
//默認(rèn)被執(zhí)行的任務(wù)列表
grunt.registerTask('default', ['uglify','concat'])
- 運(yùn)行程序
grunt,命令行中顯示如下圖,證明運(yùn)行成功了

- 此時(shí)會(huì)發(fā)現(xiàn)在 dest 文件夾下新增了一個(gè) all.min.js 文件
all.min.js
/*! create by 2017-11-25 */
var index=index||{};(index={init:function(i){console.log("index init")}}).init();
/*! create by 2017-11-25 */
function test(t){this.a=1}test.prototype.method_name=function(){console.log(this.a)};
這個(gè)文件將壓縮好的 index.min.js 和 main.min.js 文件給合并在了一起
- 還有一個(gè)是
watch插件,它主要是可以在運(yùn)行程序后,你又去修改 類(lèi)似于 index.js 這樣的文件后,它可以自動(dòng)觀察到你的修改操作自動(dòng)執(zhí)行 后面自定義的行為 (uglify,concat)
編輯 gruntfile.js 文件
//觀察本地文件的變化,讓他去可以工作
watch: {
//這里以數(shù)組的方式設(shè)置需要觀察的文件
files:['js/index.js','js/main.js'],
//這里是以數(shù)組的方式定義需要執(zhí)行的任務(wù)列表
tasks:['uglify','concat']
}
//默認(rèn)被執(zhí)行的任務(wù)列表
grunt.registerTask('default', ['uglify','concat','watch'])
10 . 此時(shí)運(yùn)行程序 grunt,你會(huì)發(fā)現(xiàn)在命令行中程序并沒(méi)有結(jié)束

然后再編輯器中修改 index.js 文件
var index = index || {};
index = {
init:function(argument) {
console.log('index ok');
}
}
index.init();
ctrl + s 保存相應(yīng)的操作,你會(huì)發(fā)現(xiàn)在命令行中又多了幾行操作提示,是說(shuō)它觀察到了 你修改了 index.js 文件 然后它又自動(dòng)重新執(zhí)行了一遍 uglify concat 任務(wù)

查看此時(shí)的 index.min.js 和 all.min.js 文件,會(huì)發(fā)現(xiàn)它們也將你剛才修改的一些代碼進(jìn)行了同步
index.min.js
/*! create by 2017-11-25 */
var index=index||{};(index={init:function(i){console.log("index ok")}}).init();
all.min.js
/*! create by 2017-11-25 */
var index=index||{};(index={init:function(i){console.log("index ok")}}).init();
/*! create by 2017-11-25 */
function test(){this.a=1}test.prototype.method_name=function(){console.log(this.a)};
修改 main.js 文件,也會(huì)得到相應(yīng)的更新,這便是 watch 觀察插件的作用
- 更多的使用技巧可以到官網(wǎng)自行查看學(xué)習(xí)
參考鏈接:http://www.gruntjs.net/sample-gruntfile Gruntfile 實(shí)例
http://www.gruntjs.net/creating-tasks 創(chuàng)建任務(wù)
