fbpx

Grunt JS 教學 - 請黃牛幫忙壓縮 JavaScript 與 CSS

關於 Grunt JSgrunt-logo-254x300

C 語言有 Make、Java 有 Ant、Node.JS 也需要一個 Task Runner,那就是 Grunt JS 囉。Grunt JS 提供我們一個可以管理與實現自動化工作的框架,而且還提供了很多好用的 Plugins。當我們開發的 Web 產品要上線時,常為了可以將低頻寬與增進效能,都會對程式碼進行一些優化工作。今天我們要介紹如何使用 Grunt JS 幫我們 Web Project 中的 JavaScript 與 CSS 程式碼進行最小化(包含產生 JavaScript Source Maps)。

安裝 Node.JS

安裝請直接到 Node.JS 官方網站下載即可,如果是 Linux 可直接透過套件管理進行安裝,這裡就不多做說明囉,以下是 Windows 的安裝畫面:

nodejs-indtall

透過 NPM 安裝 GruntJS

安裝好 Node.JS 可以直接透過 NPM 安裝 GruntJS,請輸入以下命令安裝 GruntJS Cli:

npm install -g grunt-cli

接著我們建立一支 package.json 專案檔,由於我們待會需要最小化 CSS 與 JavaScript,因此需要引用相關的 Plugins,package.json 內容如下:

{
    "name": "my-web-project",
    "version": "1.0.0",
    "description": "GruntJS build task",
    "private": true,
    "devDependencies": {
        "grunt": "~0.4.5",
        "grunt-contrib-uglify": "~0.5.0",
        "grunt-contrib-cssmin": "~0.10.0"
    }
}

上述檔案中我們引用了 uglify 與 cssmin 這兩個套件,然而「"private": true」是聲明這個 package.json 並不是要進行散佈是用,不這樣宣告執行時會有一些不必要的 Warning Message 產生。

接著輸入以下命令初始化專案,過程中會一併自動下載與安裝相依套件:

npm install

建立 Task Script 執行腳本

C 語言 make 建構腳本透過 makefile 檔案,Java Ant 建構腳本透過 build.xml,一樣的道理 GruntJS 也需要建構腳本檔,也就是 Gruntfile.js 檔案,我們先來看一下我們的檔案內容長什麼樣子,如下:

module.exports = function(grunt) {
    // Project configuration.
    grunt.initConfig({
        // 引用 package.json 中的參數
        pkg: grunt.file.readJSON('package.json'),
        // 設定 JavaScript 壓縮 task
        uglify: {
            myTask: {
                options: {
                    // 設定壓縮後檔頭要插入的註解
                    banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
                    // 使用 SourceMap 並且將 JS Source 與 Map 檔案放在一起
                    sourceMap: true,
                    sourceMapIncludeSources: true
                },
                files: [
                    {
                        expand: true,
                        cwd: 'js',
                        // 將不是 .min.js 的檔案全部進行壓縮
                        src: ['**/*.js', '!*.min.js'],
                        dest: 'js'
                    }
                ]
            }
        },
        // 設定 CSS 壓縮 task
        cssmin: {
            minify: {
                expand: true,
                cwd: 'css',
                src: ['**/*.css', '!*.min.css'],
                dest: 'css'
            }
        }
    });

    // Load the plugin.
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');

    // Default task(s).
    grunt.registerTask('default', ['uglify', 'cssmin']);
};

大概說明一下 Gruntfile.js 中的設定,其中有兩個主要的 task uglify 與 cssmin,分別用在處理 JavaScript 與 CSS 的最小化工作。由於一開始透過「pkg: grunt.file.readJSON('package.json')」引入了 package.json 中的參數,因此我們之後可以透過 <%= pkg.XXXX %> 來讀取參數值。在上述的設定中,dest 與 cwd 的目錄相同,表示這些動作會覆蓋原本的檔案,如果您不想覆蓋原檔而想要產生新的檔案,也可以加入「ext: '.min.js'」這樣的設定來達成。上述的 SourceMap 設定中,我們將程式原始碼與 Map File 放在一起,這樣上線的時候只要直接移除 Map File 即可,比較方便。

由於 JavaScript 經過最小化後,程式中的變數與函數名稱會被簡化,程式碼變得難以閱讀。為了除錯方便,產生了 Source Maps 技術。Source Maps 是一種讓最小化後的程式碼可以直接連接原始碼的一種技術,為了讓開發者可以直接在最小化後的程式碼中進行除錯,透過 Map File 可以還原程式碼,在大部分主流的瀏覽器除錯工具都有提供這樣的功能。想要讓瀏覽器載入 Map File 有以下兩種方式:

  1. 在 JavaScript 中加入特定註解「//# sourceMappingURL=/path/to/file.js.map」
  2. 透過 HTTP Header 設定 Map File 位置「X-SourceMap: /path/to/file.js.map」

GruntJS Uglify 是使用第一種方法載入 Map File,我們可以看到被最小化後的 JS 尾端會被自動加入上述的註解,好告訴瀏覽器到哪裡載入 Map File,其他 Souce Maps 詳細的資訊可以參考這份文件。Chrome 要開啟 Source Maps 功能只要在開發者工具中的設定選項,將「Enable JavaScript source maps」打勾即可,如下:

chrome-source-maps

參考資料

發佈留言