w3ctech

grunt动态任务

看了网上很多关于grunt, gulp之类的文章, 都很推荐用后者, 但我想说的是谁有谁的优点, 最适合自己项目的才是真爱... (由于本人使用的是grunt, 本人介绍她相关的一些东东)

fsdf

grunt的优点

  • 他的文档,API很全
  • 开源的插件多
  • 项目成熟,功能稳定

grunt的缺点

  • 读取文件频繁(但感觉在酷睿的天下这都不是事了, 且借用去哪网某神的说法: 我们是SSD _)
  • 为了完成需要编写大量任务逻辑js, 比如要做到 复制->编译->压缩->合并->监听->http最少需要100行代码

grunt demo

测试demo, 需要是把 src/js/ 下的所有js复制到 build/js/ 下,并把所有的js压缩成 *.min.js, 来看看任务配置吧... (代码能力有限)

// 包装函数
module.exports = function(grunt) {

    // 任务配置
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),//读取配置文件

        //复制
        copy: {
            demo: {
                files: [{
                    expand: true,
                    cwd: 'src/js/',//相对目录
                    src: '**/*.js',//源文件
                    dest: 'build/js/',//生成到的目录
                    filter: 'isFile'
                }]
            }
        },

        //js压缩
        uglify: {
            demo: {
                files: [{
                    expand: true,
                    cwd: 'build/js/',//相对目录
                    src: '**/*.js',//源文件
                    dest: 'build/js/',//生成到的目录
                    filter: 'isFile',
                    ext: '.min.js'
                }]
            }
        }
    });

    // 加载连接文件插件
    grunt.loadNpmTasks('grunt-contrib-copy');//复制
    grunt.loadNpmTasks('grunt-contrib-uglify');//js压缩

    // 测试合并任务
    grunt.registerTask('default', ['copy:demo', 'uglify:demo']);

}

然后cmd运行grunt搞定, 当然你必须得有环境和依赖包...

这只是一个小小的需求, 如果说有很多需求,比如各种合并,跨路径压缩,css处理,自动sprite,less,sass等需求, 那么你的任务js就越来越大... 且在团队开发中不太有利, 也会造成工作量加大... 我们该怎么解决呢... 愁... 但当某天我在github上见到一人设置 "动态任务" ,顿时眼前一亮, 然后...

动态设置任务

什么叫动态设置任务呢? 我给的定义是, 根据自己的需求, 来自动的生成任务并执行任务, 然后可以结合配置文件来快速的构建前端工具方案了...

我们这样定义:

  • package.json 为配置文件,只要配置一些依赖包,版本号等

  • app.json 为应用包, 主要编写实际的应用任务

app.json应用格式:


{
    "home": {//项目名
        "css": {//处理css
            "demo": {
                "src": "1.css"
            },

            "demo2": {
                "src": [
                    "1.css", "2.css", "3.css"
                ]
            },

            "demo3": {
                "src": [
                    '1.css',
                    '2.css'
                ],
                "dest": 'global.css'
            },

            ...
        },

        "js": {//处理js
            ...
        }
    }
}

然后我们的任务是这样的:

/**
 * 初始化css
 * @description 如果配置有dest, 则把所有的src合并为dest
 */
grunt.registerTask("init-css", "初始化css", function(type, name, noSprite) {
    var result;

    app = 当前实例


    // 省略N多代码...


    //如果有依赖包
    if (app.dest) {

        result = {//提前声明好用
            dest: app.dest,
        }

        if (app.src) {//如果有源
            result.src = app.src;
        }

    }


    if(result && result.src){//如果有src才算真爱,

        //动态设置任务并执行
        grunt.config.set('concat.init', result);
        grunt.task.run('concat:init');
    } else {
        console.log("app."+ type +".css."+ name +" 包里没有配置源css值, 如: src");
    }
});


/**
 * 编译css
 * @description 负责把css编译到 build 目录,并压缩,合并
 */
grunt.registerTask("build-css", "编译css", function(type, name) {
    var result;


    app = 当前实例

    // 省略N多代码...





    //处理源到build, 但不压缩
    if(app.src){
        // 复制
        result = {
            files: [{
                expand: true,
                cwd: '源目录',
                src: app.src,
                dest: '编译目录',
                filter: 'isFile'
            }]
        }

        //动态设置任务并执行
        grunt.config.set('copy.src', result);
        grunt.task.run('copy:src');
    }


    if(app.dest){//如果有依赖处理

        result = {//提前声明好用
            dest: app.dest,
        }

        if (app.src) {//如果有源
            result.src = app.src;
        }





        if(result.src ){

            //合并
            grunt.config.set('concat.dest', result);
            grunt.task.run('concat:dest');


            //压缩
            grunt.config.set('cssmin.dest', {
                src: app.dest,
                dest: app.dest
            });
            grunt.task.run('cssmin:dest');
        }
    }




    if(app.src){//如果有源则压缩源
        grunt.config.set('cssmin.src', {
            files:  [{
                expand: true,
                cwd: 编译目录,
                src: app.src,
                dest: 编译目录,
                filter: 'isFile'
            }]
        });
        grunt.task.run('cssmin:src');
    }

});

注: 以上代码只是事例说明, 具体代码视需求定!

动态设置任务的优化

  • 只要需要开发模式后, 只需要配置应用包就可以各种帅
  • 因为总入口是一个, so扩展性极强, 什么sprite, less,sass, http监听, 本地调度等一切不是梦

总结

我晕, 貌似说了很多费话, 其实核心的思路是: 根据应用配置文件来动态的设置任务! 对, 就这一句话... 但你可以扩展出自己项目所需的模式, 比如无敌模式, 自恋模式等...

最后致谢 grunt, nodejs 让前端更轻松!

前端圈微信

扫码关注前端圈微信公众号

共收到3条回复

  • 欢迎交流前端工具, 啦啦啦...

    回复此楼
  • dfafa

    回复此楼
  • asdfasf

    回复此楼