在講之前先談談大致步驟:安裝nodejs -> 全局安裝grunt -> 項目創建package.json --> 項目安裝grunt以及grunt插件 -> 配置Gruntfile.js -> 運行任務 1.安裝Node 我們開始之前需要安裝Nodejs,如果沒有安裝的 傳送門 安裝好了之後,查看 ...
在講之前先談談大致步驟:安裝nodejs -> 全局安裝grunt -> 項目創建package.json --> 項目安裝grunt以及grunt插件 -> 配置Gruntfile.js -> 運行任務
1.安裝Node
我們開始之前需要安裝Nodejs,如果沒有安裝的 傳送門
安裝好了之後,查看是否安裝成功,正常是這樣的提示
這裡建議npm換成淘寶的cnpm,速度杠杠的。
安裝命令:
npm install cnpm -g -registry=https://registry.npm.taobao.org
2.安裝全局Grunt
安裝命令:
cnpm install grunt -g
3.項目創建package.json
在項目根目錄下創建package.json文件,文件內容如下
4.項目安裝grunt以及grunt插件
我們所需要的插件
插件名稱 | 說明 | Github地址 |
grunt-contrib-clean | 清空文件和文件夾 | https://github.com/gruntjs/grunt-contrib-clean |
grunt-contrib-copy | 複製文件和文件夾 | https://github.com/gruntjs/grunt-contrib-copy |
grunt-contrib-concat | 連接、合併文件(沒用到) | https://github.com/gruntjs/grunt-contrib-concat |
grunt-contrib-cssmin | (CSS文件)壓縮 | https://github.com/gruntjs/grunt-contrib-cssmin |
grunt-contrib-uglify | (JS文件)壓縮 | https://github.com/gruntjs/grunt-contrib-uglify |
grunt-filerev | 文件內容hash(MD5)(版本號控制) | https://github.com/yeoman/grunt-filerev |
grunt-usemin | 文件進行引用修改 | https://github.com/yeoman/grunt-usemin |
load-grunt-tasks | oad-grunt-tasks | https://github.com/sindresorhus/load-grunt-tasks |
我們打開我們的項目文件夾,在路徑欄中輸入cmd然後回車
回車後的界面
打開命令行視窗之後,我們輸入安裝命令:
cnpm install grunt grunt-contrib-clean grunt-contrib-copy grunt-contrib-concat grunt-contrib-cssmin grunt-contrib-uglify grunt-filerev grunt-usemin load-grunt-tasks --save-dev
5.配置Gruntfile.js (這是重點,重點,重點。重要的事情說三遍。)
先貼一下我的配置,後面慢慢說明
1 module.exports = function (grunt) { 2 require('load-grunt-tasks')(grunt); 3 4 var path = { 5 src : 'test', 6 dest : 'dist', 7 } 8 9 grunt.initConfig({ 10 path : path, 11 clean : {//清空生產文件夾 12 beforebuild : { 13 files : [{ 14 src : ['<%= path.dest %>/'] 15 } 16 ] 17 } 18 }, 19 filerev : {//對css和js文件重命名 20 build : { 21 files : [{ 22 src : ['<%= path.dest %>/**', 23 '!<%= path.dest %>/page/*.html',//html文件不加版本號 24 '!<%= path.dest %>/**/*.{png,jpg,jpeg}']//圖片 不需要加版本號 25 } 26 ] 27 } 28 }, 29 useminPrepare : {//聲明concat、cssmin、uglify 30 build : { 31 files : [{ 32 src : '<%= path.src %>/page/*.html' 33 } 34 ], 35 36 } 37 }, 38 usemin : {//修改html中的css和js引用 39 html : { 40 files : [{ 41 src : '<%= path.dest %>/page/*.html' 42 } 43 ] 44 } 45 }, 46 copy : {//複製文件 47 build : { 48 files : [{ 49 expand : true,//為true啟用cwd,src,dest選項 50 cwd : '<%= path.src %>/',//所有src指定的匹配都將相對於此處指定的路徑(但不包括此路徑) 51 src : ['**/*.*'],//相對於cwd路徑的匹配模式。意思就是 src/**/*.*,匹配src下麵所有文件 52 dest : '<%= path.dest %>/'//目標文件路徑首碼。 53 } 54 ] 55 } 56 }, 57 cssmin :{ 58 build : { 59 files : [{ 60 expand : true,//為true啟用cwd,src,dest選項 61 cwd : '<%= path.src %>/',//所有src指定的匹配都將相對於此處指定的路徑(但不包括此路徑) 62 src : ['css/*.css'],//相對於cwd路徑的匹配模式。意思就是 src/**/*.css,匹配src下麵所有css文件 63 dest : '<%= path.dest %>/'//目標文件路徑首碼。 64 } 65 ] 66 } 67 }, 68 uglify :{ 69 build : { 70 files : [{ 71 expand : true,//為true啟用cwd,src,dest選項 72 cwd : '<%= path.src %>/',//所有src指定的匹配都將相對於此處指定的路徑(但不包括此路徑) 73 src : ['js/*.js'],//相對於cwd路徑的匹配模式。意思就是 src/**/*.js,匹配src下麵所有js文件 74 dest : '<%= path.dest %>/'//目標文件路徑首碼。 75 } 76 ] 77 } 78 }, 79 }); 80 grunt.registerTask('default', ['clean:beforebuild', 'copy', 'cssmin', 'uglify','filerev', 'usemin']); 81 };
我們前面一直都在安裝這個安裝那個,但是安裝的這些東西怎麼用起來了?
首先我們通過學習 grunt入門 瞭解到插件如何使用,這是官網的例子。
pkg是通過讀取package.json生成的json對象。
uglify是 grunt-contrib-uglify 指定的任務名,每個插件都有對應的任務名,可以在對應的github裡面查看
grunt.loadNpmTasks('grunt-contrib-uglify'); 從字面上就可以看出來/,載入能夠提供"uglify"任務的插件。
grunt.registerTask('default', ['uglify']); 註冊別名任務,這個別名任務對應的是一個任務列表
當通過 grunt 別名時,實際是執行列表裡的任務,並按順序執行
這些基本的信息都可以通過官網查看。
我們來說說我們需求,我們需要對靜態文件打包壓縮,並且需要對靜態文件加入版本號而且所有引用靜態文件的html或css都得修改文件名,我們的需求明確後來來看看我們怎麼做。
第一步:我們需要重新打包,那就需要複製文件,所以我們需要grunt-contrib-copy插件。
在copy之前我們先要確定源文件和目標文件,我這裡源文件都放在test文件夾中,目標文件都放在dist文件夾中
我們創建文件路徑
1 var path = { 2 src : 'test', 3 dest : 'dist', 4 }
文件路徑創建好了,我們來看copy
1 copy : {//複製文件 2 build : { 3 files : [{ 4 expand : true,//為true啟用cwd,src,dest選項 5 cwd : '<%= path.src %>/',//所有src指定的匹配都將相對於此處指定的路徑(但不包括此路徑) 6 src : ['**/*.*'],//相對於cwd路徑的匹配模式。意思就是 src/**/*.*,匹配src下麵所有文件 7 dest : '<%= path.dest %>/'//目標文件路徑首碼。 8 } 9 ] 10 } 11 },
從代碼的註釋就可以看出一二了。這裡說下cwd,src,dest 。
其實這裡的源路徑是 cwd + src。這才是真正的源路徑。dest是目標路徑首碼。
我這裡的意思是src下麵所有的文件,意思就是把 src文件夾 裡面的文件複製到 dest文件夾 里。這裡可以指定需要複製的具體文件夾或者文件類型
第二步:進行文件壓縮,我這裡只是針對js和css壓縮,對img的壓縮可以查看對應的插件,思路都一樣。
css壓縮需要用到 grunt-contrib-cssmin 插件,該插件對應的任務名為 cssmin
1 cssmin :{ 2 build : { 3 files : [{ 4 expand : true,//為true啟用cwd,src,dest選項 5 cwd : '<%= path.src %>/',//所有src指定的匹配都將相對於此處指定的路徑(但不包括此路徑) 6 src : ['css/*.css'],//相對於cwd路徑的匹配模式。意思就是 src/**/*.css,匹配src下麵所有文件 7 dest : '<%= path.dest %>/'//目標文件路徑首碼。 8 } 9 ] 10 } 11 },
js 壓縮需要用到 grunt-contrib-uglify 插件,該插件對應的任務名為 uglify
1 uglify :{ 2 build : { 3 files : [{ 4 expand : true,//為true啟用cwd,src,dest選項 5 cwd : '<%= path.src %>/',//所有src指定的匹配都將相對於此處指定的路徑(但不包括此路徑) 6 src : ['js/*.js'],//相對於cwd路徑的匹配模式。意思就是 src/**/*.js,匹配src下麵所有文件 7 dest : '<%= path.dest %>/'//目標文件路徑首碼。 8 } 9 ] 10 } 11 },
第三步:靜態文件重命名,我們這裡的版本控制是通過對靜態文件重命名來現實的。
重命名需要用到 grunt-filerev 插件,該插件對應的任務名為 filerev
1 filerev : {//對css和js文件重命名 2 build : { 3 files : [{ 4 src : ['<%= path.dest %>/**', 5 '!<%= path.dest %>/page/*.html',//html文件不加版本號 6 '!<%= path.dest %>/**/*.{png,jpg,jpeg}']//圖片 不需要加版本號 7 } 8 ] 9 } 10 },
這裡只有一個src參數,傳的是個數組,我們這裡是只想給css和js重命名,其他文件不需要。所以數組第一個參數 src/** 匹配src文件夾中所有文件,後面兩個 ! xx,是排除的意思,
第四步:修改html中css和js的引用
修改文件引用需要用到 grunt-usemin 插件,該插件對應的任務名為 usemin
1 usemin : {//修改html中的css和js引用 2 html : { 3 files : [{ 4 src : '<%= path.dest %>/page/*.html' 5 } 6 ] 7 } 8 },
這裡也只有一個src參數,給出的是html的地址,如果你還有css 可以這樣寫
1 usemin : {//修改html中的css和js引用 2 html : { 3 files : [{ 4 src : '<%= path.dest %>/page/*.html' 5 } 6 ] 7 }, 8 css :{ 9 files : [{ 10 src : '<%= path.dest %>/css/*.css' 11 } 12 ] 13 } 14 },
這裡需要註意 :usemin 除了需要在 Gruntfile.js中配置外,還需要在需要修改引用的文件中加入指令。 <!-- build:type path --> 具體可以在github查看,上面有地址。
(但是在idea中我沒加也可以,不知道是什麼原因。)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <title>Grunt</title> 5 <!-- build:js ../../css/common/common.css --> 6 <link href="../../css/common/common.css" type="text/css" rel="stylesheet"> 7 <!-- endbuild --> 8 </head> 9 <body> 10 <div class="wrap"> 11 </div> 12 <!-- build:js ../js/constants.js--> 13 <script src="../../js/tools/constants.js"></script> 14 <!-- endbuild --> 15 </body> 16 </html>
第五步:我們從 複製,壓縮,重命名,修改引用都說了一遍,這裡還少一個東西,就是我們每次複製之前需要把目標文件夾裡面的文件刪除掉。
修改文件引用需要用到 grunt-contrib-clean 插件,該插件對應的任務名為 clean
1 clean : {//清空生產文件夾 2 beforebuild : { 3 files : [{ 4 src : ['<%= path.dest %>/'] 5 } 6 ] 7 } 8 },
這裡也只有一個src參數,給出目標文件夾的地址。
所有任務到這裡就結算了。
我們註冊任務別
1 grunt.registerTask('default', ['clean:beforebuild', 'copy', 'cssmin', 'uglify','filerev', 'usemin']);
可以看到,我們這裡只是註冊了任務,並沒有應用插件。我們添加插件是聽過 load-grunt-tasks 插件完成的
1 require('load-grunt-tasks')(grunt);
這裡指令相當於我們一個個寫
1 grunt.loadNpmTasks('xxx');
Gruntfile.js 配置完了之後我們執行grunt命令就可以在目標文件夾中得到我們所需要的文件
這裡補充說明幾點:
這種寫法是動態構建文件對象 傳送門
這種寫法是文件數組格式 傳送門