天天看點

grunt入門grunt簡介grunt使用前置準備package.json寫法Gruntfile寫法jshint文法檢查

最近開始整理grunt相關知識,本文主要是作為指引文檔,具體操作均引用其他文章。文中如有引用之處會注明。

grunt簡介

grunt是什麼?

  Grunt 是一個基于任務的JavaScript工程指令行建構工具。

為什麼要使用grunt?

  一句話:自動化。對于需要反複重複的任務,例如壓縮(minification)、編譯、單元測試、linting等,自動化工具可以減輕你的勞動,簡化你的工作。當你在 Gruntfile 檔案正确配置好了任務,任務運作器就會自動幫你或你的小組完成大部分無聊的工作。

grunt使用前置準備

  Grunt和 Grunt 插件是通過 npm 安裝并管理的,npm是 Node.js 的包管理器,是以你需要先下載下傳node.js。傳送門

npm install -g grunt 
           

  這一步也可以省略,如省略需要在package.json中寫明此依賴,下面會涉及到。

  為了在指令行中使用grunt,你需要安裝Grunt指令行(CLI)。

-g表示全局安裝,部分系統需要sudo權限。

  每次運作grunt 時,他就利用node提供的require()系統查找本地安裝的 Grunt。正是由于這一機制,你可以在項目的任意子目錄中運作grunt 。如果找到一份本地安裝的 Grunt,CLI就将其加載,并傳遞Gruntfile中的配置資訊,然後執行你所指定的任務。

  使用grunt時,一般需要在你的項目中添加兩份檔案:package.json 和 Gruntfile。

package.json寫法

  用過node的人都知道項目根目錄有個package.json檔案,來描述項目基本資訊(作者,項目名稱,版本号等)和項目需要的各種子產品。

  使用grunt前需要将grunt和相關的插件安裝到項目目錄中,在根目錄中寫好package.json,将grunt和相關插件寫在devDependencies一項中,并執行安裝:

  沒錯,不指定npm安裝的子產品時,npm會自動搜尋本目錄的package.json,然後自動安裝裡面的devDependencies和dependencies裡注明的子產品。

  這一點阮一峰菊苣已經寫的很詳細了,不班門弄斧了。傳送門

注意: 運作項目前需要到根目錄執行

npm install

,要不然項目運作時會報錯

Gruntfile寫法

可參考http://www.hulufei.com/post/grunt-introduction

  此檔案被命名為 Gruntfile.js 或 Gruntfile.coffee,用來配置或定義任務(task)并加載Grunt插件的。 此文檔中提到的 Gruntfile 其實說的是一個檔案,檔案名是 Gruntfile.js 或 Gruntfile.coffee。

  grunt執行時會尋找項目裡的Gruntfile檔案。關于Gruntfile檔案的命名,據實測和大小寫關系不大,gruntfile, Gruntfile, GruntFile都是可以的,但按官網上的寫法是Gruntfile。

Gruntfile由以下幾部分構成:

  • “wrapper” 函數
  • 項目與任務配置
  • 加載grunt插件和任務
  • 自定義任務

比較常用的插件有:

  • jshint:簡單的js文法檢查,具體配置後面會講到
  • uglify:壓縮代碼,網站優化方案之一
  • concat:代碼合并,網站優化方案之一
  • watch:實時監控,當代碼發生變動時自動重新編譯,再也不用經常儲存再重新整理頁面了

示例:

module.exports = function(grunt) {

    // load tasks
    [
        'grunt-contrib-jshint',
        'grunt-contrib-qunit',
        'grunt-contrib-watch',
        'grunt-contrib-clean',
        'grunt-contrib-copy',
        'grunt-contrib-concat',
        'grunt-contrib-uglify',
        'grunt-contrib-cssmin',
        'grunt-contrib-concat',
        'grunt-contrib-less',
        'grunt-contrib-coffee',
        'grunt-usemin',
        'grunt-filerev'
    ].forEach(function(task) { grunt.loadNpmTasks(task); });


    // setup init config
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        // clean up the `dist/` directory, i.e., delete files
        clean: {
            dist: {
                src: [
                    'dist/*',

                    // funny dance to keep old versioned dist/css/*.pkg.*.css
                    '!dist/css/**',
                    'dist/css/*',
                    '!dist/css/*.pkg.*.css',

                    // funny dance to keep old versioned dist/css/*.pkg.*.js
                    '!dist/js/**',
                    'dist/js/*',
                    '!dist/js/*.pkg.*.js'
                ]
            }
        },

        // copy over `src/` files to `dist/`
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: 'src/',
                    dest: 'dist/',
                    src: [
                        '*',
                        'css/**',
                        'js/**',
                        'ico/**',
                        'img/**'
                    ],
                    filter: 'isFile'
                }]
            }
        },

        // compile LESS files in `src/less/` into CSS files
        less: {
            css: {
                options: {
                    paths: ["src/less"]
                },
                files: [
                    {
                        expand: true,
                        cwd: 'src/less',
                        src: ['*.less'],
                        dest: 'src/css/',
                        ext: '.css'
                    }
                ]
            }
        },

        // compile coffeescript files in `/src/coffee/` into JS files
        coffee: {
            glob_to_multiple: {
                expand: true,
                // flatten: true,
                cwd: 'src/coffee',
                src: ['**/*.coffee'],
                dest: 'src/js',
                ext: '.js'
            }
        },

        // prep call for usemin (target all html files)
        useminPrepare: {
            html: [
                'dist/*.html'
            ]
        },

        // final call for usemin (target all html files)
        usemin: {
            html: [
                'dist/*.html'
            ],
            options: {
                dirs: ['dist/']
            }
        },

        // revision a specific set of static files, this can be
        // extended to do more files and images too
        filerev: {
            files: {
                src: [
                    'dist/css/*.pkg.css',
                    'dist/js/*.pkg.js'
                ]
            }
        },

        // TODO - support qunit
        qunit: {
            files: ['test/**/*.html']
        },

        // validate JS files using jshint (great for catching simple bugs)
        jshint: {
            files: ['gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
            options: {
                // options here to override JSHint defaults
                globals: {
                    jQuery: true,
                    console: true,
                    module: true,
                    document: true
                },
                ignores: [
                    // enter paths to ignore here, e.g., 'src/js/jquery.js'
                ]
            }
        },

        // watch command to auto-compile files that have changed
        watch: {
            coffee: {
                files: ['src/**/*.coffee'],
                tasks: ['coffee', 'jshint']
            },
            less: {
                files: ['src/**/*.less'],
                tasks: ['less']
            }
        }
    });

    // Composite tasks...

    // run tests
    grunt.registerTask('test', ['jshint', 'qunit']);

    // like watch, but build stuff at start too!
    grunt.registerTask('dev', ['less', 'coffee', 'watch']);

    // full build of project to `dist/`
    grunt.registerTask('default', ['less', 'coffee', 'jshint', 'clean', 'copy',
                                   'useminPrepare',
                                   'concat', 'uglify', 'cssmin',
                                   'filerev',
                                   'usemin']);
};
           

  每個任務需要添加registerTask,registerTask函數第一個參數是任務名,第二個參數是執行的子任務,依次執行。

  具體寫法看官網文檔會比較好一些。傳送門

jshint文法檢查

筆者寫代碼的時候,由于遵循的風格和jshint的預設規則不符,各種報錯,讓我很是不爽。工具變成絆腳石,也是挺痛苦的。是以,需要根據個人習慣去配置一下jshint,減少不必要的報錯。

推薦一篇博文:JSHint 使用說明

在grunt中使用時,将文中的選項作為Gruntfile中jshint.options的key值,配置作為value就好。例如:

module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      files: ['Gruntfile.js'],
      options: {
        //這裡是覆寫JSHint預設配置的選項
        globals: {
          jQuery: true,
          console: true,
          module: true,
          document: true
        },
        asi: true,
        eqeqeq: false
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
};
           

繼續閱讀