前端自动化grunt的使用

  作为前端开发人员,有必要也有义务掌握前端自动化工具grunt;

这样可以极大地降低前端的复杂工作,提高工作效率,把所有的精力都投入到

编码中去。

grunt API列表

  • config
  • event
  • fail
  • file
  • log
  • option
  • task
  • template
  • util

在使用grunt构建前端自动化中,我主要使用的config、file、template以及util这几个API。

现在贴一份gruntfilejs代码,基本上前端的自动化工作都可以完成:

'use strict'

var ASSETS_DIR = 'assets/';
module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        /* jsdoc生成js文档 */
        jsdoc: {
            dist: {
                src: ['assets/scripts/test.js'],
                options: {
                    destination: 'docs'
                }
            }
        },

        /* css代码合并 */
        concat: {

        }
    });

    /*grunt-contrib-less模块,使用less预编译css文件*/
    grunt.config.merge({
        less: {
            dev: {
                files: [{
                    expand: true,
                    cwd: ASSETS_DIR + 'less/' + './',
                    src: ['*.less'],
                    dest: ASSETS_DIR + 'css',
                    ext: '.css'
                }]
            }
        }
    });

    /*grunt-contrib-sprite模块,生成雪碧图*/
    grunt.config.merge({
        sprite: {
            options: {
                banner: '/*<%=pkg.name %> <%=grunt.template.today("yyyy-mm-dd")%>*/'
            },
            all: {
                src: [ASSETS_DIR + "images/sprites/*.png"],
                engine: require('pixelsmith'),
                dest: ASSETS_DIR + "images/sprite.png",
                destCss: ASSETS_DIR + "css/sprite.css",
                padding: 10,
                algorithm: "binary-tree",
                cssVarMap: function(sprite) {
                    var iconIndex, activeIndex;
                    iconIndex = sprite.name.indexOf('icon-');
                    activeIndex = sprite.name.lastIndexOf('-active');
                    if (activeIndex > 0) {
                        // sprite.name=sprite.name.replace(sprite.name.substr(activeIndex),":active");
                    }
                    if (iconIndex === 0) {
                        sprite.name = sprite.name.replace(sprite.name.substr(0, 5), '');
                    }
                }
            }
        }
    });

    /*grunt-contrib-cssmin模块,压缩css文件*/
    grunt.config.merge({
        cssmin: {
            add_banner: {
                options: {
                    banner: '/* minify the css file <%= grunt.template.today("yyyy-mm-dd") %> */'
                },
                files: {
                    'assets/css/output.css': [ASSETS_DIR + 'css/bootstrap.css', ASSETS_DIR + 'css/home.css']
                }
            },
            minify: {
                options: {
                    banner: '/* minify the css file\n Author:lidasong\n Time: <%= grunt.template.today("yyyy-mm-dd") %>*/'
                },
                expand: true,
                cwd: ASSETS_DIR + 'dest/css/',
                src: ['*.css', '!*.min.css'],
                dest: ASSETS_DIR + 'dest/release',
                ext: '.min.css'
            }
        }
    });

    /**js、css代码检测工具,
     *grunt-contrib-jshint模块、grunt-contrib-csslint模块
     **/
    grunt.config.merge({
        jshint: {
            all: {
                options: {
                    '-W069': true,
                    '-W064': true,
                    '-W040': true
                },
                src: ['assets/scripts/*.js']
            }
        },
        csslint: {
            strict: {
                options: {
                    import: false
                },
                src: [ASSETS_DIR + 'css/*.css']
            }
        }
    });

    /*grunt-contrib-uglify模块,压缩js文件*/
    grunt.config.merge({
        uglify: {
            jscomp: {
                files: [{
                    expand: true,
                    cwd: ASSETS_DIR + 'scripts',
                    src: '**/*.js',
                    dest: ASSETS_DIR + 'dest/scripts'
                }]
            }
        },
    });

    /*grunt-contrib-copy模块,文件复制*/
    grunt.config.merge({
        copy: {
            release: {
                options: {
                    process: function(content, srcpath) {},
                    timestamp: true
                },
                expand: true,
                cwd: ASSETS_DIR + 'dest/',
                src: ['**'],
                dest: ASSETS_DIR + 'release'
                // flatten:true,
                // filter:'isFile'
            }
        }
    });

    /*grunt-contrib-clean模块,清除文件*/
    grunt.config.merge({
        clean: {
            concatCss: {
                options: {
                    force: true
                },
                src: [ASSETS_DIR + 'dest/css/']
            },
            miniCss: {
                options: {
                    force: true
                },
                src: [ASSETS_DIR + 'dest/release/']
            }
        }
    });

    /*grunt-contrib-watch模块,监控文件变化*/
    grunt.config.merge({
        watch: {
            'less-dev': {
                files: [ASSETS_DIR + 'less/*.less', ASSETS_DIR + 'less/partials/**/*.less'],
                tasks: ['less:dev']
            },
            'less-bootstrap': {
                files: [ASSETS_DIR + 'less/lib/bootstrap/**/*.less'],
                tasks: ['less:bootstrap']
            }
        }
    });
    /*grunt-contrib-*模块加载*/
    require('load-grunt-tasks')(grunt);

    /*grunt注册任务列表*/
    grunt.registerTask('default', ['less:dev', 'watch:less-dev']);
    grunt.registerTask('bootstrap', ['less:bootstrap']);
    grunt.registerTask('js-hint', 'JS代码质量检查', ['jshint']);
    grunt.registerTask('css-lint', 'CSS代码质量检查', ['csslint']);
    grunt.registerTask('all-concat', 'css 代码合并', ['clean:concatCss', 'css-concat', 'concat']);
    grunt.registerTask('minify-css', 'CSS代码压缩', ['clean:miniCss', 'cssmin:minify']);
    grunt.registerTask('doc', 'jsdoc生成js文档', ['jsdoc']);
    grunt.registerTask('sprites', '生成雪碧图', ['sprite:all']);
    grunt.registerTask('js-comp', '压缩js代码', ['uglify:jscomp']);
    grunt.registerTask('copyCss', '复制合并压缩后的css', ['copy:release']);
    grunt.registerTask('css-concat', 'css代码合并', function() {
        grunt.file.expand(ASSETS_DIR + 'css/*').forEach(function(dir) {
            var dirName = dir.substr(0, dir.indexOf('.')),
                concat = grunt.config.get('concat') || {};
            dirName = dirName.substr(dirName.lastIndexOf('/') + 1);
            if (grunt.file.isFile(dir)&&dirName !== 'bootstrap' && dirName !== 'sprite') {
                concat['options'] = {
                    stripBanners: true,
                    banner: '/*合并css后的代码*/'
                };
                concat[dirName] = {
                    src: [dir, ASSETS_DIR + 'css/bootstrap.css'],
                    dest: ASSETS_DIR + 'dest/css/' + dirName + '.css'
                };
                grunt.config.set('concat', concat);
            }
        });
    });
};
使用grunt.file:
grunt.file.readJSON可以读取文件的json内容返回;使用grunt.file.readJSON('package.json')读取package文件,然后使用文件的内容。
grunt.file.expand返回包含匹配给定通配符模式的文件或者目录路径的特殊数组,可以对返回的特殊数组走处理;比如此处的gruntfile文件中有grunt.registerTask中使用grunt.file.expand('文件夹path').forEach(function(dir){...});这个任务就是将文件夹中的每个原始文件使用grunt-contrib-concat执行合并操作。
当然grunt.file还有很多方法,比如目录操作:grunt.file.mkdir;复制操作:grunt.file.copy等等,这里就不一一列举。
分离grunt.initConfig({})初始化函数
首先grunt.initConfig({})函数就是grunt.config.init的另一种初始化形式;为了让grunt.initConfig函数简短,每个功能更加明晰,这个使用grunt.config的方法实现每个任务都简单明了,也使得grunt.initConfig不再那么臃肿;当然也可以使用模块化的方式将每个任务分离出gruntfile文件,然后使用commonJS的模块加载方式把每一个任务文件加载到gruntfile中来。但是我使用的是前者,直接在gruntfile文件中,使用grunt.config的方法把每个人物分离出来,单个处理。
grunt.config.set('task',taskTool)方法实现在grunt.initConfig(configObject)中的configObject添加任务;
grunt.config.merge(taskObject)同样方法实现在configObject中合并taskObject,从而添加任务。
grunt.template使用
grunt.template主要实现使用数据将模板渲染出来:
var obj = {
  foo: 'c',
  bar: 'b<%= foo %>d',
  baz: 'a<%= bar %>e'
};
grunt.template.process('<%= baz %>', {data: obj}) 

  使用grunt.template。process(template,data);把data渲染到template中,呈现结果,比如上面的输出结果是:

'abcde'

总结:

其实前端自动化还是比较好学,当然也是相当好用的,在繁杂的前端工作中,这可以减少相当一部分工作,
尤其是雪碧图的合成。学习基础的nodejs,然后熟悉grunt的api,你就可以欢快的使用自动化工具解决那些繁杂的
琐事了。

 

posted on 2015-06-03 17:32  木公2014  阅读(436)  评论(0编辑  收藏  举报