1. 程式人生 > >grunt常用配置項說明

grunt常用配置項說明



下面簡單對一些常用外掛做個介紹

minify: {
        static_mappings: {
            //由於這裡的src-dest檔案對映時手動指定的, 每一次新的檔案新增或者刪除檔案時,Gruntfile都需要更新
            files: [
                {src: 'lib/a.js', dest: 'build/a.min.js'},
                {src: 'lib/b.js', dest: 'build/b.min.js'},
                {src: 'lib/subdir/c.js', dest: 'build/subdir/c.min.js'},
                {src: 'lib/subdir/d.js', dest: 'build/subdir/d.min.js'}
            ]
        },
        dynamic_mappings: {
            //當'minify'任務執行時Grunt將自動在"lib/"下搜尋"**/*.js", 然後構建適當的src-dest檔案對映,因此你不需要在檔案新增或者移除時更新Gruntfile
            files: [ 
                {   
		    // 當你希望處理大量的單個檔案時,這裡有一些附加的屬性可以用來動態的構建一個檔案. 這些屬性都可以指定在Compact和Files Array對映格式中(這兩種格式都可以使用)。
                    expand: true, // 設定true用於啟用下面的選項
                    cwd: 'lib/', //匹配相對lib目錄的src來源  相對於當前路徑所匹配的所有src路徑(但不包括當前路徑。)
                    src: '**/*.js', //實際的匹配模式 相對於cwd路徑的匹配模式
                    dest: 'build/', //目標路徑字首 flatten 從生成的dest路徑中移除所有的路徑部分。
                    ext: '.min.js' // 使用這個屬性值替換生成的dest路徑中所有實際存在檔案的副檔名(比如我們通常將壓縮後的檔案命名為.min.js)
                    rename 對每個匹配的src檔案呼叫這個函式(在執行ext和flatten之後)。傳遞dest和匹配的src路徑給它,這個函式應該返回一個新的dest值。 如果相同的dest返回不止一次,每個使用它的src來源都將被新增到一個數組中。
		}
            ]
        }
    }
/*
  *匹配任意數量的字元,但不匹配/
  ?匹配單個字元,但不匹配/
  **匹配任意數量的字元,包括/,只要它是路徑中唯一的一部分
  {}允許使用一個逗號分割的列表或者表示式
  !在模式的開頭用於否定一個匹配模式(即排除與模式匹配的資訊)
*/
//可以指定單個檔案
{src: 'foo/this.js', dest: …}
//或者指定一個檔案陣列
{src: ['foo/this.js', 'foo/that.js', 'foo/the-other.js'], dest: …}
//或者使用一個匹配模式
{src: 'foo/th*.js', dest: …}

//一個獨立的node-glob模式
{src: 'foo/{a,b}*.js', dest: …}
//也可以這樣編寫
{src: ['foo/a*.js', 'foo/b*.js'], dest: …}

//foo目錄中所有的.js檔案,按字母排序
{src: ['foo/*js'], dest: …}
//這裡首先是bar.js,接著是剩下的.js檔案按字母排序
{src: ['foo/bar.js', 'foo/*.js'], dest: …}

//除bar.js之外的所有的.js檔案,按字母排序
{src: ['foo/*.js', '!foo/bar.js'], dest: …}
//所有.js檔案按字母排序, 但是bar.js在最後.
{src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: …}

//模板也可以用於檔案路徑或者匹配模式中
{src: ['src/<%= basename %>.js'], dest: 'build/<%= basename %>.min.js'}
//它們也可以引用在配置中定義的其他檔案列表
{src: ['foo/*.js', '<%= jshint.all.src %>'], dest: …}


    // 清理一個空的目錄
    clean: {
        foo: {
            src: ['temp/**/*'],
	    /*
               1、filter 它通過接受任意一個有效的fs.Stats方法名或者一個函式來匹配src檔案路徑並根據匹配結果返回true或者false。
               2、nonull 當一個匹配沒有被檢測到時,它返回一個包含模式自身的列表。否則,如果沒有任何匹配項時它返回一個空列表。
               3、dot 它允許模式模式匹配句點開頭的檔名,即使模式並不明確檔名開頭部分是否有句點。
               4、matchBase 如果設定這個屬性,缺少斜線的模式(意味著模式中不能使用斜線進行檔案路徑的匹配)將不會匹配包含在斜線中的檔名。 例如,a?b將匹配/xyz/123/acb但不匹配/xyz/acb/123
               5、expand 處理動態的src-dest檔案對映
	    */
            filter: function(filepath){  // 提供一個有效的fs.Stats方法
                return (grunt.file.isDir(filepath) && require('fs').readdirSync(filepath).length === 0);
            }
        }
    }
所有的檔案格式都支援srcdest屬性,只有簡潔和檔案陣列格式才支援以上的幾個屬性。簡潔格式:
bar: {
            src: ['src/bb.js', 'src/bbb.js'], // 可以只有src屬性
            dest: 'dest/b.js'
        }
檔案資料格式:
files: [
                {src: ['src/bb.js', 'src/bbb.js'], dest: 'dest/b/', nonull: true},
                {src: ['src/bb1.js', 'src/bbb1.js'], dest: 'dest/b1/', filter: 'isFile'}
            ]


2.    grunt-contrib-coffee (v0.7.0) 編譯coffee檔案為javascript檔案

 // compile the coffeescript files to javascript
        coffee: {
            dist: {
                files: [
                    {
                        expand: true,
                        cwd: '<%= yeoman.app %>/scripts',
                        src: '{,*/}*.coffee',
                        dest: '.tmp/scripts',
                        ext: '.js'
                    }
                ]
            },
            test: {
                files: [
                    {
                        expand: true,
                        cwd: 'test/spec',
                        src: '{,*/}*.coffee',
                        dest: '.tmp/spec',
                        ext: '.js'
                    }
                ]
            }
        },

     // concat任務將所有存在於src/目錄下以.js結尾的檔案合併起來,然後儲存在dist目錄中,並以專案名來命名
	  concat: {
          options: {
            separator: ';' // 定義一個用於插入合併輸出檔案之間的字元
          },
          dist: {
            src: ['src/**/*.js'], // 用於連線的檔案
            dest: 'dist/<%= pkg.name %>.js' // 返回的JS檔案位置
         }
       }
// <% %>執行任意內聯的JavaScript程式碼,對於控制流或者迴圈來說是非常有用的。
// 執行grunt concat:sample時將通過banner中的/* abcde */連同foo/*.js+bar/*.js+bar/*.js匹配的所有檔案來生成一個名為build/abcde.js的檔案。

grunt.initConfig({
    concat: {
        sample: {
            options: {
                banner: '/* <%= baz %> */\n' // '/* abcde */\n'
            },
            src: ['<%= qux %>', 'baz/*.js'], // [['foo/*js', 'bar/*.js'], 'baz/*.js']
            dest: 'build/<%= baz %>.js'
        }
    },
    //用於任務配置模板的任意屬性
    foo: 'c',
    bar: 'b<%= foo %>d', // 'bcd'
    baz: 'a<%= bar %>e', // 'abcde'
    qux: ['foo/*.js', 'bar/*.js']
});



 // Put files not handled in other tasks here
        copy: {
            dist: {
                files: [
                    {
                        expand: true,
                        dot: true,
                        cwd: '<%= yeoman.app %>',
                        dest: '<%= yeoman.dist %>',
                        src: [
                            '*.{ico,png,txt}',
                            '.htaccess',
                            'bower_components/**/*',
                            'images/{,*/}*.{gif,webp,svg}',
                            'styles/fonts/*',
                            'img/*',
                            'extensionModules/**/*',
                            '!extensionModules/**/*.js',
                            'modules.json',
                            'scripts/**/*'
                        ]
                    },
                    {
                        expand: true,
                        cwd: '.tmp/images',
                        dest: '<%= yeoman.dist %>/images',
                        src: [
                            'generated/*'
                        ]
                    }
                ]
            }
        },

    useminPrepare: {
            html: '<%= yeoman.app %>/index.html',
            options: {
                dest: '<%= yeoman.dist %>'
            }
        },
        usemin: {
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
            options: {
                dirs: ['<%= yeoman.dist %>']
            }
        },
       
        cssmin: {
            // By default, your `index.html` <!-- Usemin Block --> will take care of
            // minification. This option is pre-configured if you do not wish to use
            // Usemin blocks.
            // dist: {
            //   files: {
            //     '<%= yeoman.dist %>/styles/main.css': [
            //       '.tmp/styles/{,*/}*.css',
            //       '<%= yeoman.app %>/styles/{,*/}*.css'
            //     ]
            //   }
            // }
        },
      

  htmlmin: {
            dist: {
                options: {
                    /*removeCommentsFromCDATA: true,
                     // https://github.com/yeoman/grunt-usemin/issues/44
                     //collapseWhitespace: true,
                     collapseBooleanAttributes: true,
                     removeAttributeQuotes: true,
                     removeRedundantAttributes: true,
                     useShortDoctype: true,
                     removeEmptyAttributes: true,
                     removeOptionalTags: true*/
                },
                files: [
                    {
                        expand: true,
                        cwd: '<%= yeoman.app %>',
                        src: ['*.html', 'views/*.html'],
                        dest: '<%= yeoman.dist %>'
                    }
                ]
            }
        },

 imagemin: {
            dist: {
                files: [
                    {
                        expand: true,
                        cwd: '<%= yeoman.app %>/images',
                        src: '{,*/}*.{png,jpg,jpeg}',
                        dest: '<%= yeoman.dist %>/images'
                    }
                ]
            }
        },

jshint: {
    //定義用於檢測的檔案
    files: ['gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
    //配置JSHint (參考文件:http://www.jshint.com/docs)
    options: {
        // 你可以在這裡重寫jshint的預設配置選項
        globals: {
            jQuery: true,
            console: true,
            module: true
        }
    }
}
 jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            all: [
                'Gruntfile.js',
                '<%= yeoman.app %>/scripts/{,*/}*.js',
                '<%= yeoman.app %>/scripts/{,*/}*.js'
            ]
        },

uglify: {
    options: {
        //生成一個banner註釋並插入到輸出檔案的頂部
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
    },
    dist: {
        files: {
	    // uglify會壓縮concat任務中生成的檔案,並生成到dist/目錄下
            'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
    }
}

    壓縮一個原始檔以及使用該元資料動態的生成一個banner註釋 
    pkg: grunt.file.readJSON('package.json'), // pkg是定義了一個非任務的屬性,並且用readJSON讀取檔案資料
    uglify: {
        options: {
            banner: '/* <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
        },
        dist: {
            src: 'src/<%= pkg.name %>.js',
            dest: 'dist/<%= pkg.name %>.min.js'
        }
    }
uglify: {
            options: {
                mangle: true  // mingle
            },
            dist: {
                files: [
                    {
                        expand: true,     // Enable dynamic expansion.
                        cwd: '<%=yeoman.app %>/extensionModules',      // Src matches are relative to this path.
                        src: ['**/*.js'], // Actual pattern(s) to match.
                        dest: '<%=yeoman.dist %>/extensionModules',   // Destination path prefix.
                        ext: '.js'   // Dest filepaths will have this extension.
                    },
                    {
                        expand: true,     // Enable dynamic expansion.
                        cwd: '<%=yeoman.app %>/scripts',      // Src matches are relative to this path.
                        src: ['**/*.js'], // Actual pattern(s) to match.
                        dest: '<%=yeoman.dist %>/scripts',   // Destination path prefix.
                        ext: '.js'   // Dest filepaths will have this extension.
                    }
                ]
            }
        } // code compression


16. grunt-contrib-watch (v0.5.3) 實時監測檔案的增刪改狀態,狀態改變時自動執行預定義任務

watch: {
            coffee: {
                files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
                tasks: ['coffee:dist']
            },
            coffeeTest: {
                files: ['test/spec/{,*/}*.coffee'],
                tasks: ['coffee:test']
            },
            livereload: {
                options: {
                    livereload: LIVERELOAD_PORT
                },
                files: [
                    '<%= yeoman.app %>/{,*/}*.html',
                    '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
                    '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
                    '{.tmp,<%= yeoman.app %>}/modules/{,*/}*.js',
                    '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
                ]
            }
        },

 // run a  webserver on local host.
        connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, yeomanConfig.app)
                        ];
                    }
                }
            },
            test: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            dist: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, yeomanConfig.dist)
                        ];
                    }
                }
            }
        },

20. grunt-contrib-handlebars (v0.5.11) 預編譯Handlebars模板到JST檔案(Handlebars:結合json資料的模版)

21. grunt-contrib-jasmine (v0.5.2) 通過PhantomJS執行jasmine(PhantomJS:JS單元測試)

22. grunt-contrib-jst (v0.5.1) 預編譯Underscore模板到JST檔案(Underscore:JS工具庫)

23. grunt-contrib-nodeunit (v0.2.1) 執行Nodeunit單元測試(NodeUnit:Node.js單元測試框架)

24. grunt-contrib-qunit (v0.3.0) 用PhantomJS物件執行QUnit單元測試

'use strict';

var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT });
var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    try {
        yeomanConfig.app = require('./bower.json').appPath || yeomanConfig.app;
    } catch (e) {
    }

    grunt.initConfig({
        yeoman: yeomanConfig,
               
        open: {
            server: {
                url: 'http://localhost:<%= connect.options.port %>'
            }
        },
        // not used since Uglify task does concat,
        // but still available if needed
        /*concat: {
         dist: {}
         },*/
        rev: {
            dist: {
                files: {
                    src: [
                        '<%= yeoman.dist %>/styles/{,*/}*.css',
                        '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
                        '<%= yeoman.dist %>/styles/fonts/*'
                    ]
                }
            }
        },
 
        concurrent: {
            server: [
                'coffee:dist'
            ],
            test: [
                'coffee'
            ],
            dist: [
                'coffee',
                'imagemin',
                'htmlmin'
            ]
        },
        karma: {
            unit: {
                configFile: 'karma.conf.js',
                singleRun: true
            }
        },
        cdnify: {
            dist: {
                html: ['<%= yeoman.dist %>/*.html']
            }
        },
        
    });

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'connect:livereload',
            'open',
            'watch'
        ]);
    });

    grunt.registerTask('test', [
        'clean:server',
        'concurrent:test',
        'connect:test',
        'karma'
    ]);

    grunt.registerTask('build', [
        'clean:dist',
        'useminPrepare',
        'concurrent:dist',
        'concat',
        'copy',
        'cdnify',
        'cssmin',
        'uglify',
        'rev',
        'usemin'
    ]);

    grunt.registerTask('default', [
        //'jshint',
        'test',
        'build'
    ]);
};