Grunt+Bower基礎教程,入門篇
Grunt+Bower的簡單應用
前言
首先要感謝那些知名的不知名的前輩們,你們的成就是我們進步的基礎。
本文針對的讀者是那些像之前的我一樣剛剛瞭解Grunt和Bower這兩個名字是什麼,但還不知道究竟是幹什麼的,同樣是以應用為主,已經會基本使用這些的就不需要看了,因為都是最基礎的一些東西,同樣如果您看了之後發現有什麼不符合邏輯或常識的問題,或是有什麼錯誤,我會非常期待您的指正。
1.安裝nodeJS
grunt以及其外掛都是需要依賴nodejs來執行的,所以如果你的電腦中並沒有安裝,那麼需要安裝nodejs,安裝過程極其簡單,就是傻瓜式的下一步直到install即可
這是官網開啟以後的圖,我們這裡安裝左邊的就可以了。
安裝完成以後,win+r cmd 開啟命令提示符視窗,輸入node -v檢視版本號,以驗證nodejs是否安裝成功
2.安裝grunt-CLI
這裡就與傳統的安裝軟體方式不同了,以後安裝的一些外掛基本都是使用這樣的方式安裝的,所以先不用問這是什麼東西,用的時間長了就明白是個什麼東西了
首先使用nodejs的npm install方式安裝grunt-CLI ,很簡單,就是在命令列裡輸入npm install -g grunt-cli 然後回車鍵
分析一下這句安裝命令分別代表什麼:
npm install :nodejs的安裝外掛方式
-g:全域性安裝
grunt-cli:外掛名
確保電腦聯網且網足夠快
如果安裝成功的話會出現grunt-cli的目錄結構,安裝失敗找出原因重新安裝即可,成功後類似這樣:
進行驗證看是否安裝成功:
命令列輸入grunt 回車鍵,證明grunt-cli安裝成功
grunt-cli到這裡基本上就安裝完成了,接下來建立一個自己的前端專案吧。
3.構建專案目錄結構
這裡可以1.自己先建立一個簡單的進行練手,2.也可以學習以下yoman這類可以直接構建目錄結構的工具(npm install -g yo),3.或者是參考一些優秀的前端工程目錄結構。
這裡用一個簡單的例子做練手,更加方便練習,但如果想要更加專業化,還是參考上邊2、3方法
在D盤或者你的任意目錄下建立一個資料夾,我的是D:\1Project Workspace\New_Test_Project,然後在這個資料夾中建立需要的資料夾和檔案
接下來要建立一個名叫package.json的檔案,有兩種建立方式:
1直接建立文字並儲存為json檔案,內容為:
{
"name": "new_test_project",
"version": "1.0.0",
"description": "test",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "ds",
"license": "ISC"
}
其中左邊的名稱是不可以更改的,右邊的一些相當於引數的東西是可以進行更改的。
2.(推薦)在當前也就是D:\1Project Workspace\New_Test_Project這個目錄下shift+右鍵開啟命令列,輸入npm init,回車鍵然後按照所需資訊一步一步填寫下來,專案名必須都是小寫字母,版本號、簡介等都可以不填寫,一路回車下來,最後輸入yes,就會發現這個檔案已經建立好了:
4.安裝grunt
接下來就是正主grunt的安裝了,這裡首先介紹一下更改npm下載源的方法,網足夠好的可以跳過4.1的步驟接著往下看
4.1將下載源從國外改到淘寶
由於國外網路受網路波動影響大,時常導致下載失敗,所以我們的淘寶團隊將這些國外的映象到了國內。
官方:這是一個完整 npmjs.org
映象,你可以用此代替官方版本(只讀),同步頻率目前為 10分鐘 一次以保證儘量與官方服務同步。
執行:
npm install cnpm -g --registry=https://registry.npm.taobao.org
;
注意:安裝完後最好檢視其版本號cnpm -v或關閉命令提示符重新開啟,安裝完直接使用有可能會出現錯誤;
注:cnpm跟npm用法完全一致,只是在執行命令時將npm改為cnpm(以下操作將以cnpm代替npm)。
4.2正式安裝
執行安裝命令之前看一下4.1的最後一句話。
在剛才建立的專案目錄中開啟命令提示符,執行:cnpm install grunt --save-dev
命令分析:
cnpm install: npm方式安裝,用淘寶資料來源
grunt:我們要安裝外掛的名字
--save-dev: 在當前目錄安裝grunt的同時,順便把grunt儲存為這個目錄的開發依賴項,執行後開啟package.json後就可已發現新增加了開發依賴項grunt
小tips:這裡的名字和--save-dev是可以更換的,不會影響到執行結果,以後類似的命令同樣適用,例如本次命令用cnpm
install --save-dev grunt 執行的效果是相同的
首次安裝:會出現目錄結構
如果目錄中多了node_modules資料夾,說明安裝成功了
這時開啟package.json檔案,就會發現多了一些程式碼
而其中devDependencies的意思就是
然後新建一個名叫Gruntfile.js的檔案在專案根目錄下,它的作用是用來將我們需要配置的任務(Task)寫到裡邊去執行的,所以先建立一個空檔案
這裡要注意的是Gruntfile.js的G是大寫,其它小寫
經過以上幾個步驟,我們可以認為grunt已經安裝成功了,並且分析以上提示:Task ‘default’ not found。 說明我們該配置任務(Task)了,也就是在Gruntfile.js檔案中寫一些任務
5.配置Gruntfile.js(寫Task)
開啟Gruntfile.js輸入以下官方規定的資訊,這個指令碼檔案的規範就是這樣的,所以沒有為什麼。
看原始碼,我們已經讀取了package.json檔案中的資訊
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//這裡要寫之後的任務
});
//default任務,即預設任務,執行命令為grunt或grunt default
grunt.registerTask('default',[]);
//這是之後配置的稍複雜的任務,這裡我們先註釋掉,稍後解釋。
//grunt.registerTask('import',['wiredep']);
//grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
//grunt.registerTask('start',['connect','watch:start']);
};
這裡我們配置好了一個叫default(預設)的任務,它的任務列表,也就是右邊的陣列是空的,所以它可以啟動但是不執行什麼任務,這裡我們執行這個任務的方式就是在命令提示符中輸入grunt或 grunt default,可以得到如下結果同時我們再回去看一眼原始碼,其它註釋掉但有內容的執行方式分別是:grunt import ; grunt package ; grunt start。而其後邊的陣列中就是它依次要去執行的任務,那這些任務是如何配置的呢,接下來就一一介紹
6.寫Task(grunt常用外掛介紹)
這裡要用到的就是grunt的外掛了,這些外掛都是從官網被稽核後才能上架下載的,當然我們不需要去官網再艾格尋找下載,用我們的npm方式安裝即可,但有興趣的依然可以去官網看一眼
外掛分為兩類。第一類是grunt團隊貢獻的外掛,這些外掛的名字前面都帶有“contrib-”字首,而且在外掛列表中有星號標註。第二類是第三方提供的外掛,不帶有這兩個特徵。
並不是所有的外掛都需要被用到,這裡我們只去介紹一些我們用到的,常用的,並且每個外掛配置的不同,其用法也不盡相同:
- grunt-contrib-uglify——壓縮javascript程式碼
- grunt-contrib-jshint——javascript語法錯誤檢查
- grunt-contrib-watch——實時監控檔案變化、呼叫相應的任務重新執行
- grunt-wiredep——bower+grunt-wiredep依賴庫自動注入(自動將bower下載的包匯入html中)
- grunt-contrib-connect——可配置一個web server伺服器
- grunt-usemin——根據註釋替換到 CSS/JS 等資源引用(將原本引用的js、css自動改成釋出版本的合併後的js、css)
- grunt-contrib-copy——複製檔案,從一個資料夾複製到另一個資料夾
- grunt-contrib-concat——合併多個檔案的程式碼到一個檔案中(合併js,css)
接下來會大致講解以下這些外掛的用法,但不會詳細介紹,只是應用,官網中還有許多更加優秀實用的外掛,可以自行查詢使用
先從應用的角度來看,我們先講connect外掛和watch外掛,有了這兩個之後,我們的前端開發就可以這邊儲存,瀏覽器中自動重新整理看效果了
6.1grunt-contrib-connec
這個外掛的作用是配置一個web server伺服器,這樣我們的前端用記事本都能開發了,這裡推薦用IDE:WebStorm開發前端,因為它可以將命令提示符和grunt整合到開發工具中,用起來很方便,這裡不細說了,以下為配置詳情:
安裝方法:命令提示符輸入 cnpm install grunt-contrib-connect --save-dev
同以前一樣,我們將這個配置儲存到我們的package.json中
安裝完成,下面介紹用法:開啟Gruntfile.js修改一些配置
module.exports = function(grunt){
// LiveReload的預設埠號,你也可以改成你想要的埠號
var lrPort = 35729;
var serveStatic = require('serve-static');
var serveIndex = require('serve-index')
// 使用connect-livereload模組,生成一個與LiveReload指令碼
// <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>
var lrSnippet = require('connect-livereload')({ port: lrPort });
// 使用 middleware(中介軟體),就必須關閉 LiveReload 的瀏覽器外掛
var lrMiddleware = function(connect, options, middlwares) {
return [
lrSnippet,
// 靜態檔案伺服器的路徑 原先寫法:connect.static(options.base[0])
serveStatic(options.base[0]),
// 啟用目錄瀏覽(相當於IIS中的目錄瀏覽) 原先寫法:connect.directory(options.base[0])
serveIndex(options.base[0])
];
};
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//這裡要寫之後的任務
//connect配置,自動載入web server伺服器
connect: {
options: {
protocol: 'http',
port: 8081,
hostname: '*',
open:true,
/*keepalive: true,*/
base: ['./']
},
livereload: {
options: {
// 通過LiveReload指令碼,讓頁面重新載入。
middleware: lrMiddleware
}
}
},
});
//引入外掛
grunt.loadNpmTasks('grunt-contrib-connect');
//default任務,即預設任務,執行命令為grunt或grunt default
grunt.registerTask('default',['connect']);
//兩個任務名字不同可同時存在,執行時只要輸入grunt+名字即可,如下:grunt start
grunt.registerTask('start',['connect']);
//這是之後配置的稍複雜的任務,這裡我們先註釋掉,稍後解釋。
//grunt.registerTask('import',['wiredep']);
//grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
//grunt.registerTask('start',['connect','watch:start']);
};
task配置完成,程式碼中也註釋了語句分別是什麼,然後我們執行一下任務伺服器配置成功,當然這時實時修改檔案並不能直接讓瀏覽器重新整理,我們還需要一個監聽外掛,即grunt-contrib-watch
6.2grunt-contrib-watch
作用:實時監控檔案變化、呼叫相應的任務重新執行,即配置檔案的監聽,在檔案有變動時候執行task
安裝方法:命令提示符輸入 cnpm install grunt-contrib-watch --save-dev
安裝具體過程同上就不具體說了,不同的地方就是需要配置新的任務,直接給出配置後的Gruntfile.js詳情
module.exports = function(grunt){
// LiveReload的預設埠號,你也可以改成你想要的埠號
var lrPort = 35729;
var serveStatic = require('serve-static');
var serveIndex = require('serve-index')
// 使用connect-livereload模組,生成一個與LiveReload指令碼
// <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>
var lrSnippet = require('connect-livereload')({ port: lrPort });
// 使用 middleware(中介軟體),就必須關閉 LiveReload 的瀏覽器外掛
var lrMiddleware = function(connect, options, middlwares) {
return [
lrSnippet,
// 靜態檔案伺服器的路徑 原先寫法:connect.static(options.base[0])
serveStatic(options.base[0]),
// 啟用目錄瀏覽(相當於IIS中的目錄瀏覽) 原先寫法:connect.directory(options.base[0])
serveIndex(options.base[0])
];
};
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//這裡要寫之後的任務
//connect配置,自動載入web server伺服器
connect: {
options: {
protocol: 'http',
port: 8081,
hostname: '*',
open:true,
/*keepalive: true,*/
base: ['./']
},
livereload: {
options: {
// 通過LiveReload指令碼,讓頁面重新載入。
middleware: lrMiddleware
}
}
},
//watch的配置(監聽器)
watch:{
start:{
files: ['*.html', 'css/*', 'js/*', 'images/**/*','dist/*','src/*','src/js/*'],
options: {
livereload: lrPort
}
}
},
});
//引入外掛
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
//default任務,即預設任務,執行命令為grunt或grunt default
grunt.registerTask('default',['connect']);
//兩個任務名字不同可同時存在,執行時只要輸入grunt+名字即可,如下:grunt start
grunt.registerTask('start',['connect','watch:start']);
//這是之後配置的稍複雜的任務,這裡我們先註釋掉,稍後解釋。
//grunt.registerTask('import',['wiredep']);
//grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
//grunt.registerTask('start',['connect','watch:start']);
};
然後命令列執行task:grunt start
可以直接自動開啟瀏覽器,並且進入到伺服器的資料夾中,說明本地的資料夾已經放到伺服器上,可以進行訪問了
設定好對應檔案的監聽之後,我們可以看到當檔案進行修改之後,會生成如下日誌,並自動重新整理頁面
6.3常用外掛配置介紹
本文中所有任務Gruntfile.js原始碼及講解:
module.exports = function(grunt){
// LiveReload的預設埠號,你也可以改成你想要的埠號
var lrPort = 35729;
var serveStatic = require('serve-static');
var serveIndex = require('serve-index')
// 使用connect-livereload模組,生成一個與LiveReload指令碼
// <script src="http://127.0.0.1:35729/livereload.js?snipver=1" type="text/javascript"></script>
var lrSnippet = require('connect-livereload')({ port: lrPort });
// 使用 middleware(中介軟體),就必須關閉 LiveReload 的瀏覽器外掛
var lrMiddleware = function(connect, options, middlwares) {
return [
lrSnippet,
// 靜態檔案伺服器的路徑 原先寫法:connect.static(options.base[0])
serveStatic(options.base[0]),
// 啟用目錄瀏覽(相當於IIS中的目錄瀏覽) 原先寫法:connect.directory(options.base[0])
serveIndex(options.base[0])
];
};
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//uglify的配置(js壓縮)
uglify: {
options: {
// 此處定義的banner註釋將插入到輸出檔案的頂部
mangle: false, //不混淆變數名
preserveComments: 'some', //不刪除註釋,還可以為 false(刪除全部註釋),some(保留@preserve @license @cc_on等註釋
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
options: {
report: "min",//輸出壓縮率,可選的值有 false(不輸出資訊),gzip
},
files: {
//uglify會自動壓縮concat任務中生成的檔案
'dist/js/app.min.js': ['dist/js/app.js']
}
}
},
//jshint的配置(程式碼校驗)
jshint:{
build:['src/js/test.js'],
options:{
//這裡是覆蓋JSHint預設配置的選項
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
//watch的配置(監聽器)
watch:{
build:{
files:['src/*.js'],
tasks:['jshint','uglify'],
options:{spawn:false}
},
start:{
files: ['*.html', 'css/*', 'js/*', 'images/**/*','dist/*','src/*','src/js/*'],
options: {
livereload: lrPort
}
}
},
//wiredep的配置(自動將bower下載的包匯入html中)
wiredep: {
target: {
src: ['src/*.html'],
directory:"js/libs"
}
},
//connect配置,自動載入web server伺服器
connect: {
options: {
protocol: 'http',
port: 8081,
hostname: '*',
open:true,
/*keepalive: true,*/
base: ['./']
},
livereload: {
options: {
// 通過LiveReload指令碼,讓頁面重新載入。
middleware: lrMiddleware
}
}
},
useminPrepare: {
html: 'src/*.html',
options: {
dest: 'dist'
}
},
usemin: {
html: ['dist/*.html']
},
//copy任務,將src下的copy到dist
copy:{
js:{
expand:true,
cwd:'src/',
src:['*.html'],
dest:'dist/',
},
},
//合併
concat:{
options: {
separator: ';',
stripBanners: true,
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
src: ['src/js/*.js'],
dest: 'dist/js/app.js',
}
},
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-wiredep');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-usemin');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('import',['wiredep']);
grunt.registerTask('package', ['copy:js','useminPrepare','concat:dist','uglify:dist','usemin']);
grunt.registerTask('start',['connect','watch:start']);
}
以上的三個任務:grunt import、grunt package、grunt start都是我自行進行任務組合配置的,當然如果你足夠熟悉每一種外掛的作用,完全可以自己進行相應任務的調配。
這些外掛的首次安裝方式都為:cnpm install 外掛名 --save-dev ,這裡就不去一一描述了,下載自己需要的外掛就可以了
7.釋出正式版及外掛批量安裝
我們在釋出正式版本的時候,是不需要node_modules這個資料夾的,但在開發的時候是需要的,所以我們在釋出正式版本的時候,是需要將我們的原始碼修改為釋出版本之後,保留我們的Gruntfile.js以及package.jsonjson,在命令提示符中輸入npm install 即可生成一個node_modules資料夾並安裝在package.json的devDependencies中所有的外掛,有可能由於網路波動導致安裝失敗,多裝幾次就行了。
如果你想測試一下如上所說的話,將目錄中的node_modules刪掉,輸入npm install即可。
8.整合bower
我們已經知道了前端開發時,可以進行使用一些外掛以協助我們開發,當然當專案上線的時候,是不需要這些外掛的。而我們專案中所用到的一些外掛,如bootstrap,jquery這些常用的外掛,我們需要去官網找並下載原始碼,那麼有沒有一種方式來簡化這個過程呢,當然,這就是bower
8.1 bower安裝
bower大概的意義就是專案中的包管理
安裝方法:npm install -g bower
其中-g的意思是全域性安裝
當我們使用bower進行包的安裝時,其路徑並不是我們的安裝路徑
所以我們引入一個.bowerrc檔案,注意是以“.”開頭的,其內容為:
{
"directory": "js/libs"
}
這樣,我們通過bower安裝的檔案路徑就都為:js下的lib中了
8.2 初始化
bower安裝完成後需要進行初始化:
即在命令提示符中輸入 bower init,同npm init相同的,也需要輸入一些資訊,當然也可以一路回車,然後最後確定即可。可以發現目錄中的多了bower.json檔案
{
"name": "new_test_project",
"description": "test",
"main": "index.js",
"authors": [
"ds"
],
"license": "ISC",
"homepage": "",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
8.3 包的安裝
這裡我們用jquery舉例
安裝方法:命令提示符bower install --save jquery
然後bower
就會從遠端下載jquery
最新版本到你的js/lib
目錄下
其中--save
引數是儲存配置到你的bower.json
,你會發現bower.json
檔案已經多了一行:
我們到資料夾中去看,專案根目錄下的js/libs多了jquery的原始檔
8.4 包的資訊
命令提示符輸入:bower info jquery
即可看到jquery
的bower.json
的資訊,和可用的版本資訊
8.5包的更新
想要修改jquery的版本,只要修改bower.json中為:
"dependencies": {
"jquery": "~1.11.3"
}
然後執行 bower update 就可以就行版本的切換了
8.5 包的查詢
命令提示符輸入bower search +關鍵字, 如bower search bootstr,即可搜尋出包含bootstr欄位的所有可用的包
8.6包的解除安裝
包的解除安裝為unstall命令
如jquery的解除安裝:bower uninstall jquery