前言
現在前端自動化已經是家常便飯,各種工具也是層出不窮,grunt、gulp、webpack是應用最廣的三種工具,雖然grunt看似已垂垂老矣,但是以前寫的很多項目一直用的就是grunt,溫故方能知新,這里把grunt的基本操作再記錄一下。
grunt常用插件
開始使用grunt很簡單,在項目的根目錄中添加兩份文件:package.json 和 Gruntfile.js。npm安裝模塊和插件的操作就不細說了,主要是在Gruntfile.js中填寫配置代碼。代碼目錄結構如下:
然后我們就來介紹最常用的幾個插件:
合並:grunt-contrib-concat
合並代碼是我們最需要的一個功能了,當項目變大並且模塊很多的時候,就拿我們這個angular的單頁應用項目來說,index頁面會有一列的js代碼,如下圖所示:
我們需要將這些js合並為一個文件,大大減少網絡請求數量因此來提升性能。grunt-contrib-concat完美勝任,下面我們來看看基本配置用法:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
allInOne: {
src: ['src/js/*.js'],
dest: 'dest/js/<%= pkg.name %>.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['concat']);
};
將src/js中所有js文件合並為一個js,放在dest/js目錄下,名字為package.json中項目name。這時候項目目錄中就會出現一個dest的文件夾,如下所示:
壓縮:grunt-contrib-uglify
合並文件后,體積仍然比較大,上線之前要將代碼壓縮,因此我們接着將上一步合並后的代碼壓縮,這里就需要用到grunt-contrib-uglify插件。仍然直接上配置代碼:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
allOne: {
src: ['src/js/*.js'],
dest: 'dest/js/<%= pkg.name %>.js'
}
},
uglify: {
buildrelease: {
options: {
report: "min" //輸出壓縮率
},
files: [{
expand: true,
cwd: 'dest/js', //js目錄
src: '**/*.js', //所有js文件
dest: 'dest/js', //輸出到此目錄下
ext: '.min.js' //指定擴展名
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['concat', 'uglify:buildrelease']);
};
這里我將concat后的js文件仍然輸出到當前目錄dest/js下,如下圖所示:
引用替換:grunt-usemin(grunt-contrib-copy,grunt-contrib-clean)
使用上面兩個插件合並壓縮后,每次都需要手動去html頁面中修改引用路徑,這並不是我們想要的結果,並且直接在源版本上修改也不利於測試與發布,因此首先我們需要用到grunt-contrib-copy插件,將源代碼copy一份,然后在副本上進行壓縮合並,這樣無論是全部壓縮還是部分壓縮就比較靈活了,copy之后就可以使用grunt-usemin插件了,usemin是一個多任務插件,它包括兩個任務,useminPrepare和usemin。
useminPrepare用來檢測html頁面中的腳本塊,包括腳本文件的源路徑,目的路徑,從而更新后續需要使用到的Grunt任務的配置信息,如前面使用的concat,uglify。useminPrepare只是分析文件,獲取文件及路徑信息,不更新內容。HTML中的腳本塊如下:
而usemin則進行文件引用替換,將源文件中的文件塊替換為壓縮文件。useminPrepare已經幫助我們自動配置了concat,uglify針對的源文件以及目的文件的路徑信息,因此就無需再手動配置concat和uglify任務了。配置代碼如下
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
src: 'build/'
},
useminPrepare: {
html: 'build/index.html',
options: {
dest: 'build'
}
},
uglify: {
buildrelease: {
options: {
report: "min" //輸出壓縮率
}
}
},
usemin: {
html: 'build/index.html',
options: {
dest: 'build'
}
},
copy: {
html: {
files: [{
expand: true,
cwd: 'src',
src: '**/*',
dest: 'build/'
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-usemin');
grunt.registerTask('default', ['clean', 'copy', 'useminPrepare', 'concat', 'uglify', 'usemin']);
};
上面又引入了一個clean插件,每次構建時候先清除build目錄,這樣build目錄就是我們打包后的要的結果了。目錄結構如下:
總結
以上就是grunt最基本的使用方法,為了簡單方便,插件的很多配置並沒有介紹與使用,可以在此基礎上查看官方文檔使用更強的功能即可。項目代碼使用的是大漠窮秋的angular實戰的一個Demo,也是我入門angular的資料,需要注意的是打包angular項目時候要保證嚴格的依賴注入風格,否則合並后會報錯的。