一個項目開發完成咱們總能發現有一堆js文件很是混亂。
通常在一個HTML文檔加載的時候,瀏覽器會根據HTML代碼從上到下讀取所須要加載進來的CSS、JS、圖片等文件,指定爲異步加載的文件除外。 每讀取一個文件,瀏覽器都會向Web服務器發送一個加載的請求,服務器以爲這個請求沒問題後,瀏覽器纔會開始接收文件。也就是說,每次加載一個文件都會消 耗必定的時間在服務器和客戶端的來回上。
加載一個文件消耗的時間能夠忽略不計,問題是你顯示一個複雜的網頁可能會加載N多文件,那咱們在咱們能夠控制的範圍內,能少花點時間就少花點唄。用戶但是對網頁加載的速度很挑剔的!
對圖片咱們常常會把一些圖標合併成一個大圖片用CSS的background來取得相應圖片以減小請求。CSS也一般對一種媒體只寫一個文件,固然 這邊要注意萬惡的IE對CSS的限制,參考個人博文:用SCSS須要當心IE對css的幾個限制。對JS,通常就會將本地的全部用到的文件合併及壓縮。當 然,以上對使用requireJS一類的框架加載的除外。
所謂的壓縮就是會將全部空格符、註釋等不影響代碼都移除,把長的名稱都替換爲短的名稱以節省字符。當你的JS被壓縮後,除了頭部可能會額外加點文件 註釋外,全部的JS代碼都併爲一行,不少變量名都變爲a啊a的字母,徹底失去了可讀性。而後你看到本身的JS從300KB可能縮減爲只有5KB。這樣作的 惟一目的就是把JS文件變小,使其加載的速度更快。
GruntJs是一套前端自動化工具,一個基於nodeJs的命令行工具,通常用於:css
① 壓縮文件
② 合併文件
③ 簡單語法檢查
GruntJS的安裝及使用
GruntJS是一個創建在NodeJS基礎上的任務管理工具。html
- 到NodeJS官網下載安裝適合你係統的NodeJS。現在的NodeJS安裝會自帶NPM包管理,因此你不用再另外裝NPM了。
- 用NPM裝GruntJS的CLI,因爲你要在命令行執行GruntJS的命令:
- 在開發項目根文件夾準備package.json文件。
- 將命令行指定到這個根文件夾,執行
想要在你的項目裏執行GruntJS呢,還需要下面幾步:前端
- 準備文件Gruntfile.js或Gruntfile.coffee。
- 將命令行指定到這個根文件夾,執行
package.json的配置
這個JSON文件就是給NPM包管理用的。這裏咱們僅僅要依據GruntJS官網給的一個樣例改就已足夠。具體的配置請參考官網:
https://www.npmjs.org/doc/files/package.json.html
{
"name": "demo",
"file": "zepto",
"version": "0.1.0",
"description": "demo",
"license": "MIT",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.6.3",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-uglify": "~0.2.1",
"grunt-contrib-requirejs": "~0.4.1",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-clean": "~0.5.0",
"grunt-strip": "~0.2.1"
},
"dependencies": {
"express": "3.x"
}
}
這個樣例包括了配置這個項目的名稱,項目的版本號,開發用到的NPM包。執行npm install的時候就是讀取這個devDependencies的內容,來下載對應的包到項目根文件夾的node_modules文件夾內。還可以指定下載的包的版本號。node
在這裏,咱們合併、壓縮JS需要用到2-3個NPM包。各自是:git
名稱中間帶「contrib」的爲GruntJS官方提供的插件。github
另外,演示樣例其中使用的grunt-contrib-jshint是一個用來檢查JS語法錯誤的插件,可以在你合併文件的時候就幫你檢查出錯誤。express
Gruntfile.js的配置
一個主要的Gruntfile包括下面幾部分:npm
module.exports =
function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
//
這裏放插件的設置信息
taskname: { }
});
//
加載要使用的插件
grunt.loadNpmTasks('grunt-taskname');
//
註冊任務
grunt.registerTask('default', ['grunt-taskname']);
};
整段代碼包括在一個函數中,利用了NodeJS一個把函數公開,可以被其它文件使用的一個寫法。json
合併js示例:數組
module.exports =
function (grunt) {
//
項目配置
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/login.js', 'src/reg.js', 'src/index.js'],
dest: 'dest/cdel.min.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
//
默認任務
grunt.registerTask('default', ['concat']);
}
"concat"指定了這套配置所相應的插件。"dev"是我本身定義的一個子任務,我給它取名爲"dev"。一個插件可以擁有多套不一樣的配置以應付不一樣的需求,也就是說在"concat"下可以包括隨意多個本身定義的子任務,每個子任務都可以有不一樣的配置。
這裏我設置了"banner"參數,這個參數在很是多對文件操做的插件中都有,如uglify, less, sass等等。它的做用是給終於的目標文件頭部加上一些信息或者代碼。
在這個"banner"中,我爲終於生成的app.debug.js加上了一段文件凝視。當中還使用了幾個特殊的代碼:
-
\n
-
換行符,寫入文件後,先後的字符就會分行。
-
<%= pkg.name %>
-
相似ASP的寫法。pkg是用grunt.file.readJSON('package.json')讀取到的JSON,並且已經轉換爲JS對象。依照前面package.json的演示樣例,這段代碼會在寫入文件時被替換爲"my-project-name"。
-
事實上從這裏就可以看出在grunt的配置中,咱們可以利用JS對象和JSON來作輔助的配置。
-
<%= grunt.template.today("yyyy-mm-dd") %>
-
這是利用了個grunt的方法,可以執行任務的時間並且指定生成的格式。
執行這個concat任務時,個人app.debug.js的頭部會有下面一段凝視:
/*
!
* my-project-name - JS for Debug
* @licence my-project-name - v0.1.0 (2014-07-07)
* http://blog.csdn.net/jennieji | Licence: MIT
*/
而在文件路徑的寫法上,則可以用一些匹配的符號。如我這裏用了一個星號"*.js"表示隨意名稱的JS文件,兩個星號"**"表示當前文件夾或者子文件夾下。因此這裏"js/app/"文件夾下及其所有子文件夾下的JS文件都會被合併到app.debug.js的文件裏。
配置完後,還要記得加載插件和註冊你這個任務,不然會報錯!
加載插件就是把插件NPM包的名字"grunt-contrib-concat"傳給grunt.loadNpmTasks方法。
註冊任務呢,則是用grunt.registerTask方法。第一個參數爲註冊的任務隊列的名稱,寫爲"default"則成爲這個 Gruntfile的默認任務隊列。第二個參數就是這個任務隊列要運行的任務名稱的數組,這裏的任務名稱使用在initConfig配置時使用的名稱, 即"concat"。改動代碼例如如下:
//
加載要使用的插件
grunt.loadNpmTasks('grunt-contrib-concat');
//
註冊任務
grunt.registerTask('default', ['concat']);
假設這樣寫,那配置完後直接輸入下面命令到命令行便可以運行一次JS的合併:
假設將"default"改成其它名字,比方"debug",那麼命令行需要輸入:
增長Uglify壓縮JS也作相似的配置。注意的是這邊源文件和目標文件的配置寫法不同。是在files參數裏以「目標文件路徑:[源文件路徑1,源文件路徑2,...]」的格式來寫。
壓縮js示例:
module.exports =
function (grunt) {
//
項目配置
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.file %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%=pkg.file %>.js',
dest: 'dest/<%= pkg.file %>.min.js'
}
}
});
//
加載提供"uglify"任務的插件
grunt.loadNpmTasks('grunt-contrib-uglify');
//
默認任務 grunt.registerTask('default', ['uglify']); }