引入:grunt是一套前端自動化工具,一個基於nodeJs的命令行工具,通常用於:css
環境:grunt是基於nodejs運行的,因此須要有nodejs,在Nodejs中,安裝grunt的命令行接口。html
1 npm install -g grunt-cli
將grunt命令植入系統路徑。經過nodejs的require查找到安裝的grunt,就能在任意目錄下運行grunt項目了。前端
在一個簡單的實例中,慢慢享受grunt給前端所帶來的便捷與爲所欲爲。node
新建項目的時候,增長兩個文件,一個爲:package.json;另外一個爲:Gruntfile.js。git
這個文件用來存儲npm模塊的依賴項(好比咱們的打包如果依賴requireJS的插件,這裏就須要配置)
而後,咱們會在裏面配置一些不同的信息,好比咱們上面的file,這些數據都會放到package中
對於package的靈活配置。github
這個文件尤爲關鍵,他通常幹兩件事情:
① 讀取package信息
② 插件加載、註冊任務,運行任務(grunt對外的接口所有寫在這裏面)express
Gruntfile通常由四個部分組成
① 包裝函數
這個包裝函數沒什麼東西,意思就是咱們全部的代碼必須放到這個函數裏面npm
module.exports = function (grunt) { //你的代碼 }
這個不用知道爲何,直接將代碼放入便可json
② 項目/任務配置
咱們在Gruntfile通常第一個用到的就是initConfig方法配置依賴信息less
pkg: grunt.file.readJSON('package.json')
這裏的 grunt.file.readJSON就會將咱們的配置文件讀出,而且轉換爲json對象
而後咱們在後面的地方就能夠採用pkg.XXX的方式訪問其中的數據了
值得注意的是這裏使用的是underscore模板引擎,因此你在這裏能夠寫不少東西
uglify是一個插件的,咱們在package依賴項進行了配置,這個時候咱們爲系統配置了一個任務
uglify(壓縮),他會幹這幾個事情:
① 在src中找到zepto進行壓縮(具體名字在package中找到)
② 找到dest目錄,沒有就新建,而後將壓縮文件搞進去
③ 在上面加幾個描述語言
這個任務配置其實就是一個方法接口調用,按照規範來就好,暫時不予關注,內幕後期來
這裏只是定義了相關參數,可是並未加載實際函數,因此後面立刻就有一句:
grunt.loadNpmTasks('grunt-contrib-uglify');
用於加載相關插件
最後註冊一個自定義任務(其實也是默認任務),因此咱們下面的命令行是等效的:
grunt == grunt uglify
實例:
1 js壓縮打包
package.json文件
1 { 2 "name": "demo", 3 "file": "zepto", 4 "version": "0.1.0", 5 "description": "demo", 6 "license": "MIT", 7 "devDependencies": { 8 "grunt": "~0.4.1", 9 "grunt-contrib-jshint": "~0.6.3", 10 "grunt-contrib-uglify": "~0.2.1", 11 "grunt-contrib-requirejs": "~0.4.1", 12 "grunt-contrib-copy": "~0.4.1", 13 "grunt-contrib-clean": "~0.5.0", 14 "grunt-strip": "~0.2.1" 15 }, 16 "dependencies": { 17 "express": "3.x" 18 } 19 }
1->1(一個文件打包壓縮到另外一個文件):
1 module.exports = function (grunt) { 2 banner: '/*! <%= pkg.file %>Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n' 3 }, 4 build: {6 src: 'build/js/<%=pkg.file %>.js', 7 dest: 'dist/js/<%= pkg.file %>.min.js' 8 } 9 }
N->1(N個文件打包壓縮到一個文件):
1 module.exports = function (grunt) { 2 banner: '/*! <%= pkg.file %>Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n' 3 }, 4 build: { 5 src: ['build/js/<%=pkg.file %>.js','build/js/<%=pkg.file %>1.js'],7 dest: 'dist/js/<%= pkg.file %>.min.js' 8 } 9 }
N->N(經過my_target):
1 module.exports = function (grunt) { 2 options: { 3 banner: '/*! <%= pkg.file %> Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n' 4 }, 5 my_target : { 6 files : { 7 'dist/js/index.min.js':['build/js/index.js'], 8 'dist/js/index1.min.js':['build/js/index1.js'], 9 'dist/js/index2.min.js':['build/js/index1.js'], 10 'dist/js/index3.min.js':['build/js/index1.js'] 11 } 12 } 13 }
2 less編譯打包
N->N
1 less : { 2 development: { 3 options: { 4 compress: true 5 }, 6 files: { 7 "dist/css/index1.css":"build/less/index1.less", 8 "dist/css/index.css" : "build/less/index.less" 9 } 10 } 11 }
N->1(將build/less/下的兩個文件編譯合併到dist/css/目錄下)
1 module.exports = function (grunt) { 2 less : { 3 development: { 4 options: { 5 compress: false 6 }, 7 files: { 8 "dist/css/index.css":["build/less/index1.less","build/less/index.less"] 9 } 10 } 11 }
開發模式與產品模式(惟一區別就是開發模式下,爲了進行調試,儘可能不壓縮文件,而上線版本,最好將其進行壓縮)代碼表示將build/less/下的兩個Less文件轉化爲dist/css/下的css文件,二者前者爲未壓縮版本。
1 module.exports = function (grunt) { 2 less : { 3 development: { 4 options: { 5 compress: false 6 }, 7 files: { 8 "dist/css/index.css":["build/less/index1.less","build/less/index.less"] 9 } 10 }, 11 production: { 12 options: { 13 compress: true 14 }, 15 files: { 16 "dist/css/index4.css":["build/less/index1.less","build/less/index.less"] 17 } 18 } 19 }
3 圖片優化(將圖片進行優化處理,並生成新的文件,存放在另外一個文件夾中)這裏表示,匹配build/img下面的全部以png,jpg,gif,svg,jpeg格式結尾的文件,並一一進行優化處理,而後將優化後的圖片放在dist/img/目錄下。
1 image : { 2 dynamic : { 3 files:[{ 4 expand:true, 5 cwd:'build/img/', 6 src:['**/*.{png,jpg,gif,svg,jpeg'], 7 dest:'dist/img/' 8 }] 9 } 10 } 11 });
4 js語法檢查(按照自定義的標準,檢測綁定的相關js文件是否有語法錯誤)
1 jshint : { 2 options: { 3 jshintrc :'.jshintrc' 4 }, 5 core: { 6 src:'dist/js/index.min.js' 7 }, 8 demo: { 9 src:'dist/js/index1.min.js' 10 } 11 }
5 監聽(watch):經過綁定全部的js文件及less文件,並時時監聽文件內容的變化,當變化發生時,將從新編譯、壓縮、打包生成最新的文件。
1 uglify: { 2 options: { 3 banner: '/*! <%= pkg.file %> Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n' 4 }, 5 build : { 6 src: 'build/js/index.js', 7 dest:'dist/js/index6.min.js' 8 } 9 }, 10 watch: { 11 files: ["build/less/*.less","build/js/*.js"], 12 tasks: ["less", "uglify"] 13 },
6 清理文件(構建成功後,將再也不須要的文件刪除,好比圖片優化以後,以前的圖片就能夠清理掉了)
1 clean: { 2 build: ["build/img/*"] 3 },
7 css文件校驗處理
1 csslint: { 2 options: { 3 csslintrc: 'build/less/.csslintrc' 4 }, 5 dist:[ 6 'dist/css/index1.css', 7 ] 8 }
8 連接Bootstrap HTML 並進行語法檢查
1 bootlint: { 2 options: { 3 relaxerror: ['W002','W003','W005','W007'] 4 }, 5 files: ['*.html'] 6 },
9 構建HTML模板
1 includes: { 2 build: { 3 src: ['*.html'], // Source files 4 dest: 'documentation/', // Destination directory 5 flatten: true, 6 cwd: 'documentation/build', 7 options: { 8 silent: true, 9 includePath: 'documentation/build/include' 10 } 11 }
其中css連接處理須要的.jshintrc文件以下:
1 { 2 "adjoining-classes": false, 3 "box-sizing": false, 4 "box-model": false, 5 "compatible-vendor-prefixes": false, 6 "floats": false, 7 "font-sizes": false, 8 "gradients": false, 9 "important": false, 10 "known-properties": false, 11 "outline-none": false, 12 "qualified-headings": false, 13 "regex-selectors": false, 14 "shorthand": false, 15 "text-indent": false, 16 "unique-headings": false, 17 "universal-selector": false, 18 "unqualified-attributes": false, 19 "ids": false, 20 "fallback-colors": false, 21 "vendor-prefix": false, 22 "import": false 23 }
完整的Gruntfile.js文件以下:
1 module.exports = function (grunt) { 2 grunt.initConfig({ 3 pkg: grunt.file.readJSON('package.json'), 4 uglify: { 5 options: { 6 banner: '/*! <%= pkg.file %> Qboooogle <%= grunt.template.today("yyyy-mm-dd") %> */\n' 7 }, 8 build : { 9 src: 'build/js/index.js', 10 dest:'dist/js/index6.min.js' 11 } 12 }, 13 watch: { 14 files: ["build/less/*.less","build/js/*.js"], 15 tasks: ["less", "uglify","image","clean"] 16 }, 17 concat: { 18 options: { 19 separator: ';' 20 }, 21 dist: { 22 src:["build/less/index1.less","build/less/index.less"], 23 dest:"build/less/index3.less" 24 } 25 }, 26 less : { 27 development: { 28 options: { 29 compress: false 30 }, 31 files: { 32 "dist/css/index6.css":["build/less/index1.less","build/less/index.less"] 33 } 34 }, 35 production: { 36 options: { 37 compress: true 38 }, 39 files: { 40 "dist/css/index5.css":["build/less/index1.less","build/less/index.less"] 41 } 42 } 43 }, 44 clean: { 45 build: ["build/img/*"] 46 }, 47 uglify: { 48 options: { 49 mangle:true, 50 preserveComments:'some' 51 } 52 }, 53 54 cssmin: { 55 compress: { 56 files: { 57 "dist/css/index.css": [ 58 "build/less/index1.less", 59 "build/less/index.less" 60 ] 61 } 62 } 63 } 64 image: { 65 dynamic: { 66 files: [{ 67 expand: true, 68 cwd: 'build/img/', 69 src: ['**/*.{png,jpg,gif,svg,jpeg}'], 70 dest: 'dist/img/' 71 }] 72 } 73 }, 74 csslint: { 75 options: { 76 csslintrc: 'build/less/.csslintrc' 77 }, 78 dist:[ 79 'dist/css/index1.css', 80 ] 81 }, 82 bootlint: { 83 options: { 84 relaxerror: ['W002','W003','W005','W007'] 85 }, 86 files: ['*.html'] 87 }, 88 includes: { 89 build: { 90 src: ['*.html'], // Source files 91 dest: 'documentation/', // Destination directory 92 flatten: true, 93 cwd: 'documentation/build', 94 options: { 95 silent: true, 96 includePath: 'documentation/build/include' 97 } 98 } 99 } 100 jshint : { 101 options: { 102 jshintrc :'.jshintrc' 103 }, 104 core: { 105 src:'dist/js/index.min.js' 106 }, 107 demo: { 108 src:'dist/js/index1.min.js' 109 } 110 } 111 }); 112 113 grunt.loadNpmTasks('grunt-contrib-jshint'); 114 grunt.loadNpmTasks('grunt-image'); 115 grunt.loadNpmTasks('grunt-contrib-less'); 116 grunt.loadNpmTasks('grunt-contrib-clean'); 117 grunt.loadNpmTasks('grunt-contrib-csslint'); 118 grunt.loadNpmTasks('grunt-bootlint'); 119 grunt.loadNpmTasks('grunt-includes'); 120 grunt.loadNpmTasks("grunt-contrib-concat"); 121 grunt.loadNpmTasks("grunt-contrib-watch"); 122 grunt.loadNpmTasks("grunt-contrib-uglify"); 123 grunt.loadNpmTasks('grunt-contrib-cssmin'); 124 125 grunt.registerTask('link', ['includes']); 126 grunt.registerTask('default', ['includes']); 127 // Linting task 128 //grunt.registerTask('lint', ['jshint', 'csslint', 'bootlint']); 129 130 // The default task (running "grunt" in console) is "watch" 131 //grunt.registerTask('default', ['watch']); 132 }
完整的目錄結構以下:
整項目代碼下載:Qboooogle