用grunt搭建自動化的web前端開發環境實戰教程(詳細步驟)
jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你沒有理由不學、不用!
前端自動化,這樣的一個名詞聽起來非常的有吸引力,向往力。當今時代,前端工程師需要維護的代碼變得及為龐大和復雜,代碼維護、打包、發布等流程也變得極為繁瑣,同時浪費的時間和精力也越來越多,當然人為的錯誤也隨着流程的增加而增加了更多的出錯率。致使每一個團隊都希望有一種工具,能幫助整個團隊在開發中能精簡流程、提高效率、減少錯誤率。隨之討論自動化部署也越來越多,並且國內很多大型團隊也都有自己成熟的自動化部署工具。據我所知,百度有FIS,騰訊有Modjs,360有燕尾服,還有很多團隊在使用Ant,Shell等,而現在討論較多的是Grunt。
在平常的工作之中,我們都不斷的在重復着做相同的事情,比如說將Sass編譯成CSS,檢測JavaScript語法,壓縮CSS、JavaScript。特別在團隊合作開發中,常常會為了各自的習慣而不斷的發生麻煩,給開發帶來極大的不便。而且前端開發人員在周而復始的做這些相同的,乏味的事情。很多時候我們想工作變得更有意義,更能專注於開發,就希望有一種工具能讓我們不去做這些重復而乏味的工作。這就有了Grunt,而這個Grunt讓我們編碼變得更意義,更開心。
Grunt是一個任務管理器,能大大提高您運行前端開發工作流程。使用大量的Grunt插件可以自動執行任務,例如編譯Sass和CoffeeScript,優化圖像和驗證您的JavaScript代碼與JSHint。在過去你可能使用類似CodeKit或Hammer來處理這些任務。我認為這兩種應用程序是偉大的(過去廣泛的使用他們),但Grunt比他們更優秀,他可以定制任務。有很多插件可以幫助你優化圖片和在你的工作流中加入CSS樣式。
--------------------------------
Grunt: JavaScript世界的構建工具 -- Grunt中文網
http://www.gruntjs.net/
grunt是一套前端自動化工具,一個基於nodeJs的命令行工具,一般用於:壓縮文件,合並文件,簡單語法檢查。
GRUNT JavaScript 世界的構建工具
為何要用構建工具?
一句話:自動化。對於需要反復重復的任務,例如壓縮(minification)、編譯、單元測試、linting等,自動化工具可以減輕你的勞動,簡化你的工作。當你在 Gruntfile 文件正確配置好了任務,任務運行器就會自動幫你或你的小組完成大部分無聊的工作。
為什么要使用Grunt?
Grunt生態系統非常龐大,並且一直在增長。由於擁有數量龐大的插件可供選擇,因此,你可以利用Grunt自動完成任何事,並且花費最少的代價。如果找不到你所需要的插件,那就自己動手創造一個Grunt插件,然后將其發布到npm上吧。
先看看入門文檔http://www.gruntjs.net/getting-started吧。
可用的Grunt插件
你所需要的大多數task都已經作為Grunt插件被開發了出來,並且每天都有更多的插件誕生。插件列表頁面列出了完整的清單。
Grunt和 Grunt 插件是通過 npm 安裝並管理的,npm是 Node.js 的包管理器。
提前感受一下 Grunt 吧!
安裝 grunt 雖然很簡單,更多涉及到如何運行項目。看看下面的演示,這是為項目案例運行 grunt 后的輸出。
---------------------------------
用grunt搭建自動化的web前端開發環境實戰教程
1. 前言
各位web前端開發人員,如果你現在還不知道grunt或者聽說過、但是不會熟練使用grunt,那你就真的out了。Gulp未來有可能替代grunt,但是現在來說市場占有率還是不如grunt。
2. 安裝nodejs
Grunt和所有grunt插件都是基於nodejs來運行的。
現在windows安裝nodeJS直接下載即可:https://nodejs.org/en/ 根據需要下載,下載完成后直接下一步下一步完成,就具有nodeJS環境了
安裝了nodejs之后,可以在你的控制台中輸入“node -v”來查看nodejs的版本。
注意:
一,grunt依賴於nodejs的v0.8.0及以上版本;
二,奇數版本號的版本被認為是不穩定的開發版,不過從官網上下載下來的應該都是偶數的穩定版。
三,windows下升級nodejs 僅僅需要安裝最新的msi,注意需要與原來文件夾保持一致,會自動刪除后創建(360衛士會彈出兩次阻止框需要選擇允許執行)。
3. 安裝grunt-CLI
注意,如果你的電腦不聯網,以下操作你都做不了,先保證電腦聯網。
“CLI”被翻譯為“命令行”。要想使用grunt,首先必須將grunt-cli安裝到全局環境中,使用nodejs的“npm install…”進行安裝。
打開控制台(windows系統下請使用管理員權限打開),輸入:npm install grunt-cli -g (卸載舊版本命令:npm uninstall grunt -g)
mac os 系統、部分linux系統中,在這句話的前面加上“sudo ”指令。
命令行會出現一個轉動的小橫線,表示正在聯網加載。加載的時間看你網速的快慢,不過這個軟件比較小,一般加載時間不會很長,稍一會兒,就加載完了。你會看到以下界面。
- abbrev@1.0.7 node_modules\grunt-cli\node_modules\nopt\node_modules\abbrev
C:\Users\Administrator\AppData\Roaming\npm
`-- grunt-cli@1.2.0
+-- findup-sync@0.3.0
| `-- glob@5.0.15
| +-- inflight@1.0.6
| | `-- wrappy@1.0.2
| +-- inherits@2.0.3
| +-- minimatch@3.0.3
| | `-- brace-expansion@1.1.6
| | +-- balanced-match@0.4.2
| | `-- concat-map@0.0.1
| +-- once@1.4.0
| `-- path-is-absolute@1.0.1
+-- grunt-known-options@1.1.0
+-- nopt@3.0.6
| `-- abbrev@1.0.9
`-- resolve@1.1.7
驗證grunt-cli是否安裝完成並生效,在命令行中輸入grunt,回車。
grunt-cli: The grunt command line interface (v1.2.0)
......
如果出現上面提示,說明grunt-cli安裝成功了。
安裝 grunt-init(可選)
npm install grunt-init -g
可選安裝,grunt-init是個腳手架工具,它可以幫你完成項目的自動化創建,包括項目的目錄結構,每個目錄里的文件等。
4. 創建一個簡單的網站
創建一個簡單的測試網站來演示grunt的安裝、使用。
在電腦的D盤下面創建“grunt_test”文件夾,里面建了三個空文件夾build、src、test,兩個空文檔Gruntfile.js、package.json。
Gruntfile.js //項目自動化工作流配置文件,重要(注意 Gruntfile.js 文件的首字母大寫,后綴名不能是隱藏的.txt)
package.json //項目自動化所依賴的相關插件。
package.json官方文件地址:http://gruntjs.com/getting-started#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"
}
}
name為項目名稱,version為版本,devDependencies是“開發依賴項”,即依賴於哪些插件來開發,格式為插件名:版本。
根據項目情況修改為下面內容:
{
"name": "grunt_test",
"version": "1.0.0",
"devDependencies": {
}
}
5. 安裝grunt
Grunt沒有具體的作用,但是它能把有具體作用的一個一個插件組合起來,形成一個整體效應。
grunt不是全局安裝需要在控制台進入到具體目錄下。進入 D:\grunt_test目錄下。然后輸入以下命令:npm install grunt --save-dev
“--save-dev”的意思是,為在當前目錄安裝grunt的同時,把grunt保存為這個目錄的開發依賴項。
package.json的devDependencies會自動增加"grunt": "^1.0.1"。
grunt_test目錄下多了一個“node_modules”文件夾,里面會生成很多子文件夾,這里就是存儲grunt源文件的地方。
D:\grunt_test>npm install grunt --save-dev
npm WARN prefer global coffee-script@1.10.0 should be installed with -g
grunt_test@1.0.0 D:\grunt_test
`-- grunt@1.0.1
+-- coffee-script@1.10.0
+-- dateformat@1.0.12
.......
npm WARN grunt_test@1.0.0 No description
npm WARN grunt_test@1.0.0 No repository field.
npm WARN grunt_test@1.0.0 No license field.
在控制台運行“grunt”命令。如果你得到一個warning提示,那說明grunt已經起作用了。
D:\grunt_test>grunt
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
經過以上三步,說明grunt已經在這個目錄下成功安裝,Warning警告是因為沒有配置Gruntfile.js導致的。
6. 配置Gruntfile.js
Gruntfile.js官方文件地址:http://gruntjs.com/getting-started#an-example-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' } } }); // Load the plugin that provides the "uglify" task. grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task(s). grunt.registerTask('default', ['uglify']); };
根據項目情況修改為:
module.exports = function(grunt) { //項目配置 grunt.initConfig({ //獲取package.json信息 pkg: grunt.file.readJSON('package.json') }); // 在輸入grunt命令時需要做什么任務,注意先后順序 grunt.registerTask('default', []); };
將上面內容放到Gruntfile.js保存。
上面配置說明package.json中的內容不光是用來占位置的,還可以在其他地方獲取。
再運行一下grunt命令結果為綠色的 Done.說明配置成功。
7. Grunt插件介紹
官網的插件列表 http://www.gruntjs.net/plugins
此插件列表是自動生成的,數據來自npm模塊數據庫。 官方維護的 "contrib" 插件都被標上星號圖標。第三方提供的插件,不帶contrib和星號圖標。
2016.11.19時有5692個插件了,列表前幾個插件,下載量最多,也是大家都在用的插件。
插件
最后更新時間
Grunt 版本
下載量
最近 30 天
contrib-clean 1001579 清空文件、文件夾
contrib-watch 988565 實時監控文件變化、調用相應的任務重新執行
contrib-copy 897190 復制文件、文件夾
contrib-jshint 882830 javascript語法錯誤檢查
contrib-uglify 857367 壓縮javascript代碼
contrib-concat 689029 合並多個文件的代碼到一個文件中
contrib-cssmin 513869 壓縮css代碼
contrib-less 432259 把less文件編譯成css
karma 408769 前端自動化測試工具
contrib-connect 397416 啟動一個連接的Web服務器
......
grunt集全世界web前端開發的智慧於一身,比你想想的更加強大,插件庫能應對你在web前端開發遇到的任何事情。
8. 使用uglify插件(壓縮javascript代碼)
Uglify插件的功能就是壓縮javascript代碼。幾乎每一個javascript類庫或者框架,都有一個 **.min.js 壓縮版。
要安裝一個插件,你首先要進入這個插件在grunt官網的說明文檔頁面。我們在grunt官網插件列表頁面,找到“contrib-uglify”點擊進入。
https://www.npmjs.com/package/grunt-contrib-uglify
安裝uglify插件的方式,和安裝grunt是一樣的。
npm install grunt-contrib-uglify --save-dev
先運行上面命令。安裝完成之后,可以看到package.json中“devDependencies”節點的變化,以及“node_modules”文件夾里的變化。
在現有的“src”文件夾中新建一個“test.js”,並隨便寫一些代碼,來測試壓縮javascript代碼。
在Gruntfile.js中配置:
對uglify的配置有兩項。
“options”中規定允許生成的壓縮文件帶banner,即在生成的壓縮文件第一行加一句話說明。注意,其中使用到了pkg獲取package.json的內容。
“build”中配置了源文件和目標文件。即規定了要壓縮誰?壓縮之后會生成誰?注意,我們這里將目標文件的文件名通過pkg的name和version來命名。
module.exports = function(grunt) { //項目配置 grunt.initConfig({ //獲取package.json信息 pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.name %>-<%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, build: { src: 'src/test.js', dest: 'build/<%= pkg.name %>-<%= pkg.version %>.min.js' } } }); //加載uglify插件任務 grunt.loadNpmTasks('grunt-contrib-uglify'); // 在輸入grunt命令時需要做什么任務,注意先后順序,在grunt命令執行時,立即執行uglify插件 grunt.registerTask('default', ['uglify']); };
在控制台中運行grunt命令,將輸入如下信息(注:需要先運行上面的 npm install grunt-contrib-uglify --save-dev命令):
D:\grunt_test>grunt
Running "uglify:build" (uglify) task
>> 1 file created.
Done.
到build目錄下查看是否生成了一個壓縮后的js文件:grunt_test-1.0.0.min.js,打開內容可以看到第一行注釋/*! grunt_test-1.0.0 2016-11-19 */
以上是uglify插件的詳細安裝、配置說明。Javascript使用uglify壓縮,css可使用cssmin插件壓縮,方法一樣的,其他插件也類似。
9. 使用jshint插件(檢查javascript語法錯誤)
jshint插件的安裝和配置跟uglify一樣,命令為:npm install grunt-contrib-jshint --save-dev
和uglify的配置一樣,分為“options”和“build”兩個部分。“build”中描述了jshint要檢查哪些js文檔的語法。 “options”中描述了要通過怎么的規則檢查語法,這些規則的描述文件就保存在網站根目錄下的一個叫做“.jshintrc”的文件中。
.jshintrc文件中代碼的格式也要遵守嚴格的json語法,否則無效。搜索“jshint 配置”關鍵字就可以看到常用配置:
https://my.oschina.net/u/923974/blog/306695
{
"curly": true, // true: Require {} for every new block or scope
"eqeqeq": true, // true: Require triple equals (===) for comparison
"immed": true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
"latedef": true, // true: Require variables/functions to be defined before being used
"newcap": true, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg": true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"sub": true, // true: Prohibit use of empty blocks
"undef": true, // true: Require all non-global variables to be declared (prevents global leaks)
"boss": true, // true: Require all defined variables be used
"eqnull": true, // true: Requires all functions run in ES5 Strict Mode
"es3": true, // {int} Max number of formal params allowed per function
"node": true, // {int} Max depth of nested blocks (within functions)
"-W117": true // {int} Max number statements per function
}
插件文檔里面也有例子:
{
"curly": true,
"eqnull": true,
"eqeqeq": true,
"undef": true,
"globals": {
"jQuery": true
}
}
在網站的根目錄下面添加.jshintrc文件,並把上面內容放到文件里。
注:在windows上不能直接創建文件名以“.”開頭的文件,可以在后面加上一個.,或者用命令行:echo > .jshintrc 方式創建。
加載插件沒有先后順序:grunt.loadNpmTasks('grunt-contrib-jshint');
配置grunt命令啟動時,要執行的任務,這里注意先后順序。先檢查語法通過了再合並才有意義,所以jshint在uglify之前。
配置改為:grunt.registerTask('default', ['jshint','uglify']);
module.exports = function(grunt) { //項目配置 grunt.initConfig({ //獲取package.json信息 pkg: grunt.file.readJSON('package.json'), //uglify 插件配置信息 uglify: { options: { banner: '/*! <%= pkg.name %>-<%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, build: { src: 'src/test.js', dest: 'build/<%= pkg.name %>-<%= pkg.version %>.min.js' } }, jshint: { options: { jshintrc: '.jshintrc' }, build: ['Gruntfile.js','src/*.js'] } }); //加載uglify插件 grunt.loadNpmTasks('grunt-contrib-uglify'); //加載jshint插件 grunt.loadNpmTasks('grunt-contrib-jshint'); // 在輸入grunt命令時需要做什么任務,注意先后順序,在grunt命令執行時,立即執行jshint,uglify插件 grunt.registerTask('default', ['jshint','uglify']); };
再執行grunt命令測試
Running "jshint:build" (jshint) task
Gruntfile.js
2 | //
^ This character may get silently deleted by one or more browsers.
出現上面錯誤是因為中文注釋文件編碼ansi的問題,文件編碼改成UTF8則可以解決。
Running "jshint:build" (jshint) task
>> 2 files lint free.
Running "uglify:build" (uglify) task
>> 1 file created.
Done.
出現上面內容說明執行成功。
10. 使用csslint插件(檢查css語法錯誤)
檢查css文件的語法錯誤要使用csslint插件,其安裝配置方法和jshint幾乎一模一樣。只不過csslint依賴於一個叫做“.csslintrc”的文件作為語法檢驗的規則。
https://www.npmjs.com/package/grunt-contrib-csslint
npm install grunt-contrib-csslint --save-dev
grunt.loadNpmTasks('grunt-contrib-csslint');
csslint: {
options: {
csslintrc: '.csslintrc'
},
strict: {
options: {
import: 2
},
src: ['path/to/**/*.css']
},
lax: {
options: {
import: false
},
src: ['path/to/**/*.css']
}
}
“.csslintrc”文件語法檢驗的規則
{
"qualified-headings": true,
"unique-headings": true,
"known-properties": false
}
11. 使用watch插件(真正實現自動化)
上面的插件,每次執行插件功能,都得執行一遍“grunt”命令,這樣的操作非常繁瑣,通過watch插件解決這個問題。
安裝watch插件:npm install grunt-contrib-watch --save-dev,grunt.loadNpmTasks('grunt-contrib-watch');
配置watch將監控哪些文件的變化,以及這些文件一旦變化,要立即執行哪些插件功能。
watch將監控src文件夾下所有js文件和css文件的變化,一旦變化,則立即執行jshint和uglify兩個插件功能。
module.exports = function(grunt) { //項目配置 grunt.initConfig({ //獲取package.json信息 pkg: grunt.file.readJSON('package.json'), //uglify 插件配置信息 uglify: { options: { banner: '/*! <%= pkg.name %>-<%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, build: { src: 'src/test.js', dest: 'build/<%= pkg.name %>-<%= pkg.version %>.min.js' } }, jshint: { options: { jshintrc: '.jshintrc' }, build: ['Gruntfile.js','src/*.js'] }, watch: { build: { files: [ 'src/*.js' ], tasks:['jshint','uglify'], options: { spawn: false } } } }); //加載uglify插件 grunt.loadNpmTasks('grunt-contrib-uglify'); //加載jshint插件 grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); // 在輸入grunt命令時需要做什么任務,注意先后順序,在grunt命令執行時,立即執行jshint,uglify插件 grunt.registerTask('default', ['jshint','uglify','watch']); };
運行grunt命令,控制台提示watch已經開始監聽。停止監聽按ctrl+ c即可。
既然在監聽,我們試一試看監聽有沒有效。我們將 test.js 代碼中去掉一個分號,看它能否自動檢查出來這個錯誤。
結果顯示,watch檢查到了test.js文件的變化,而且通過執行jshint提示了語法錯誤。
更重要的是,它現在還在監聽、並未停止。說明它正在等着你去修改錯誤,重新監聽檢查。
檢測到文件變化執行了jshint和uglify,執行完畢之后重新進行監聽。從而實現了自動化。
D:\grunt_test>grunt
Running "jshint:build" (jshint) task
>> 2 files lint free.
Running "uglify:build" (uglify) task
>> 1 file created.
Running "watch" task
Waiting...
>> File "src\test.js" changed.
Running "jshint:build" (jshint) task
src/test.js
8 | var b = "bbb"
^ Missing semicolon.
>> 1 error in 2 files
Warning: Task "jshint:build" failed.
Running "watch" task
Waiting...
>> File "src\test.js" changed.
Running "jshint:build" (jshint) task
>> 2 files lint free.
Running "uglify:build" (uglify) task
>> 1 file created.
Running "watch" task
Completed in 0.094s at Sat Nov 19 2016 06:35:31 GMT+0800 (中國標准時間) - Waitin
g...
^C終止批處理操作嗎(Y/N)? y
D:\grunt_test>
停止監聽按ctrl+ c即可。
12. 配置中的“build”
各個插件的配置時,都是用了“build”這一名稱作為一個配置項。而實際不一定要用build。
這里可以用任何字符串代替“build”(但要符合js語法規則)。甚至,你可以把“build”指向的內容分開來寫,把數組拆分成多個變量。這樣對多人協同開發很友好。
13. 批量安裝插件,同步開發安裝插件
在上傳代碼到開發庫的時候,不會把“node_modules”中的內容也上傳(內容很多也比較大),其他一起開發的人,怎么得到這些grunt插件和工具呢?
解決辦法是把package.json上傳上去,而package.json中的“devDependencies”就記錄了這個系統的開發依賴項,然后通過nodejs的npm即可批量安裝。
實驗方法:在D盤下面新建一個目錄“grunt_test_1”,然后把“grunt_test”中的package.json拷過去。在打開命令行跳轉到“grunt_test_1”,執行“npm install”命令,結果在“grunt_test_1”生成了“node_modules”文件夾,里面安裝好了package.json中“devDependencies”配置的插件。而且,版本都是一致的。(跟java用maven管理jar包有點類似)
package.json
{ "name": "grunt_test", "version": "1.0.0", "devDependencies": { "grunt": "^1.0.1", "grunt-contrib-csslint": "^2.0.0", "grunt-contrib-jshint": "^1.0.0", "grunt-contrib-uglify": "^2.0.0", "grunt-contrib-watch": "^1.0.0" } }
14. 系統文件結構
使用grunt來搭建web前端開發環境文檔目錄和之前可能不一樣。手動寫的代碼文件,不是最終輸出的文件。還需要經過grunt各種插件的檢驗、合並、壓縮才能最終輸出給用戶。
例如“src”文件夾里面存儲的是原始的代碼文件,“dist”文件夾里面存儲的是最終生成的代碼文件,“demo”里面存儲的是一些測試頁面。
各個系統的文件組織形式不一樣,建議大家去github上參考一下jquery、 bootstrap這些著名開源項目的文檔結構。
jquery輸出的雖然是簡單的一個js文件,但是它的開發目錄結構是很復雜的。
以上教程是本人參考網上教程一步步手動執行測試完成的,相信大部分人都可以按照這個思路完成的。