有两个目录,一个src,用来放置我们源码,(使用GIT或SVN等版本管理器只需要维护src这个目录和项目根目录中的其它文件,如Gruntfile.js、package.json)。另外一个目录是release目录,用来存放针对src目录中的代码合并、压缩、添加指纹、发布的最终输出代码。(也就是线上代码)Gruntfile任务操作我们在这里先介绍最基本的任务:合并、JS混淆压缩、CSS压缩、清除、添加指纹、替换页面中的静态资源引用。step 1:安装grunt包和任务插件;   grunt包安装 :npm install grunt --save-dev   合并插件:npm installgrunt-contrib-concat --save-dev   按照上面的插件的安装方式继续安装其它插件    JS混淆压缩 :grunt-contrib-uglify    CSS压缩:grunt-contrib-cssmin    清除:grunt-contrib-clean   添加指纹:grunt-rev   替换页面中的静态资源引用 :grunt-contrib-levin-usemin  或者根据已有的package.json文件中的devDependencies依赖项进行一次安装   npm installstep 2:完成step1后,会在项目的根目录中生成一个node_modules的包,所有的插件还有grunt都在这个包下。
接下来我们完善Gruntfile.js文件中的任务    先定义一个配置变量,可在后续的任务中直接使用config :{                                static_dest:'release/main/webapp/static/union/'               },合并任务,将release/js/文件夹下的两个js文件合并为build.js    concat:{                lib:{                    files:{                        '<%= config.static_dest %>js/build.js':[                            '<%= config.static_dest %>js/zepto.min.js',                            '<%= config.static_dest %>js/slip-min.js'                        ]                    }                }     },混淆压缩任务,将release/js/文件夹下的所有js文件进行混淆压缩
     uglify:{                options:{                    banner:'/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> *//n'                },                my_target:{                    files:[                        {                            expand:true,                            cwd:'<%= config.static_dest %>js/',                            src:'*.js',                            dest:'<%= config.static_dest %>js/'                        }                    ]                }      },css压缩任务,将release/css/文件夹下的所有css文件进行压缩
     cssmin:{                options:{                    banner:'/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> *//n',                    beautify:{                        ascii_only:true                    }                },                my_target:{                    files:[{                        expand:true,                        cwd:'<%= config.static_dest %>css/',                        src:'*.css',                        dest:'<%= config.static_dest %>css/'                    }]                }            },消除任务,将release/js/文件夹下不合并之前的js文件清除
clean:[ "<%= config.static_dest %>js/zepto.min.js", "<%= config.static_dest %>js/slip-min.js" ],添加指纹任务,将release/目录下的静态资源添加指纹(添加指纹是根据静态文件的内容生成md5其中的8位字符,所以同学们不用担心更新某一个静态文件,会导致别的静态文件的指纹发生变化)
   rev: {                options: {                    encoding: 'utf8',                    algorithm: 'md5',                    length: 8                },                assets: {                    files: [{                        src: [                            '<%= config.static_dest %>img/**/*.{jpg,jpeg,gif,png}',                            '<%= config.static_dest %>css/*.css',                            '<%= config.static_dest %>js/**/*.js'                        ]                    }]                }            },替换动态页面中的静态文件引用任务(针对静态资源引用的地址进行替换,如果有同学需要使用CDN前缀地址的话,那么大家可以使用我发布的一个grunt插件grunt-contrib-levin-usemin,这个插件大家可以用其它插件的安装方法去安装,与grunt-usemin插件不同的地方是我加了一个替换方法filePRefixer,github地址:https://github.com/levincao1/grunt-contrib-levin-usemin/)
            usemin:{                css:{                    files:{                        src:['<%= config.static_dest %>css/*.css']                    }                },                js:['<%= config.static_dest %>js/**/*.js'],                html:['<%= config.views_dest %>**/*.jsp','<%= config.views_dest %>*.jsp'],                options:{                    //替换静态文件引地址前缀                    filePrefixer:function(url){                        if(!url){                            return '';                        }                        return url.replace('../..','<%=request.getContextPath()%>');                    },                    patterns: {                        js: [                            [/(img/.png)/, 'Replacing reference to image.png']                        ]                    }                }            }声明一个发布的task
grunt.registerTask('release',['concat','uglify','clean','cssmin','rev','usemin']);运维同学添加的编译脚本build.sh
#!/bin/bash/bin/rm -rf release &&/mkdir release && /cp -r src/* release/ &&/#执行grunt发布的release任务grunt release
发布结果
通过运维的发布脚本会生成一个release目录(也就是我们上面指到的release目录)再执行grunt发布命令操作release目录下的静态资源
比较一下发布前

发布后的静态资源

发布后的新闻热点
疑难解答