chaihongjun.me

grunt压缩htm插件及CSS前缀自动补全和grunt任务执行时间统计

之前发布一篇帖子是关于前端自动化的《grunt简洁使用版(合并压缩)》,主要是介绍JS和CSS文件的压缩合并优化的。今天再来介绍3款插件:

grunt-contrib-htmlmin

grunt-autoprefixer

time-grunt

第一个就是压缩html文件的,第二个是补全CSS属性前缀,第三个是一个计时器,用来查看grunt执行任务的时长。

grunt压缩htm插件及CSS前缀自动补全和grunt任务执行时间统计

html的压缩其实很简单,大部分做法是去掉空格等操作,本身grunt-contrib-htmlmin的很多执行属性结合起来可以起到很好的压缩效果,具体参见:

https://github.com/kangax/html-minifier#options-quick-reference

博主经常使用dedecms来快速制作网站,自然而然对dedecms系统的完整也有优化的需求,如何在输出dedecms静态页面之前对dede模板做优化是博主一直思考的问题,阅读了上面的文档发现有个参数很好用ignoreCustomFragments。结合dedecms的标签写法,写出了针对Dedcms的忽略白名单以及忽略注释的白名单:

 /* 忽略dedecms {dede: ...} [field:.../]  {/dede:..} <? ... ?>  标签*/
ignoreCustomFragments: [/{dede:[\s\S]*?}/, /\[field:[\s\S]*?\/]/, /{\/dede:[\s\S]*?}/, /<\?[\s\S]*?\?>/],
 /* 忽略 dedecms 页面生成时间标签注释 */
ignoreCustomComments: [/<!--[\s]{dede:[\s\S]*?}[\s]-->/],

有了以上的代码,再使用htmlmin压缩的时候就不会出现语法报错的现象了。grunt-autoprefixer则是扫描CSS文件,使用<CAN I USE>规则自动补全被扫描文件。最后直接上GF文件:

	    //   1. 原始html,CSS,JS和图片分别在html,css,js,img目录内
	    //   2. 如果有多个JS/CSS,则合并之后仍然分别在JS,CSS目录
	    //   3. 如果只有单一JS/CSS,则分别压缩之后在opt_js,opt_css目录里
	    //   4.优化后的图片在opt_img里面
	    //   5.压缩后的html文件在opt_html里面
	    module.exports = function(grunt) {
	        'use strict';
         require('time-grunt')(grunt) ;
    // do whatever you want with the stats


    // be sure to let grunt know when to exit


	        // var mozjpeg = require('imagemin-mozjpeg');
	        grunt.initConfig({
	            /************       CSS文件处理     ************/
	            /*****    检查 CSS 语法  ****/
	            csslint: {
	                options: {
	                    csslintrc: '.csslint'
	                },
	                src: ['css/*.css']
	            },
	            /****    清理无用 CSS    ****/
	            uncss: {
	                dist: {
	                    files: {
	                        'opt_css/tidy.css': ['html/index.html']
	                    }
	                },
	                options: {
	                    report: 'gzip'
	                }
	            },
	            /****     压缩 CSS    ****/
	            cssmin: {
	                options: {
	                    report: 'gzip',
	                    keepSpecialComments: 0 /* 移除 CSS 文件中的所有注释 */
	                },
	                minify: {
	                    expand: true,
	                    cwd: 'css/',
	                    src: ['*.css'],
	                    dest: 'opt_css/',
	                    ext: '.min.css'
	                }
	            },
	            sass: {
	                dist: {
	                    files: [{
	                        expand: true,
	                        cwd: 'css/',
	                        src: ['*.scss'],
	                        dest: 'css/',
	                        ext: ['.css']
	                    }]
	                }
	            },
	            /************       CSS文件处理     ************/
	            /************       JS文件处理     ************/
	            /****      检查 js 语法    ****/
	            jshint: {
	                options: {
	                    jshintrc: '.jshint'
	                },
	                files: {
	                    src: ['Gruntfile.js', 'js/*.js']
	                },
	            },
	            /****        最小化、混淆、合并 JavaScript 文件       ****/
	            uglify: {
	                target: {
	                    files: {
	                        'js/all_in_one.js': ['js/*.js']
	                    }
	                },
	                //最小化、混淆所有 js/ 目录下的 JavaScript 文件
	                minjs: {
	                    files: [{
	                        expand: true,
	                        cwd: 'js/',
	                        src: ['**/*.js', '!**/*.min.js'],
	                        dest: 'opt_js/',
	                        ext: '.min.js'
	                    }]
	                },
	                options: {
	                    mangle: false, //不混淆变量名
	                    // preserveComments: 'all', //不删除注释,还可以为 false(删除全部注释),some(保留@preserve @license @cc_on等注释)
	                    report: 'gzip'
	                }
	            },
	            /************       JS文件处理     ************/
	            /************       图片文件处理     ************/
	            /****        压缩优化图片大小        ****/
	            imagemin: {
	                dist: {
	                    options: {
	                        optimizationLevel: 7,
	                        progressive: true,
	                        interlaced: true,
	                        pngquant: { quality: "65-80" }
	                    },
	                    files: [{
	                        expand: true,
	                        cwd: 'img',
	                        src: ['**/*.{png,jpg,jpeg|gif|svg}'], // 优化 img 目录下所有 png/jpg/jpeg 图片
	                        dest: 'opt_img/' // 优化后的图片保存位置,默认覆盖
	                    }]
	                }
	            },
	            /************       图片文件处理     ************/
	            /************      CSS JS 文件处理     ************/
	            /****    合并 JS/CSS 文件    ****/
	            concat: {
	                /****    合并 CSS 文件    ****/
	                css: {
	                    // src: ['css/*.css' ],
	                    src: ['opt_css/**/*.css'],
	                    /* 根据目录下文件情况配置 */
	                    dest: 'opt_css/all_in_one.min.css'
	                },
	                /****    合并 JS 文件    ****/
	                js: {
	                    src: ['js/**/*.js'],
	                    /* 根据目录下文件情况配置 如果可以使用 require.js/LABjs 等配置更佳 */
	                    dest: 'js/all_in_one.js'
	                }
	            },
	            /****    合并 JS/CSS 文件    ****/
	            /************      CSS JS 文件处理     ************/
	            /************     HTML 文件处理     ************/
	            //压缩HTML
	            htmlmin: {
	                options: {
	                    ignoreCustomFragments: [/{dede:[\s\S]*?}/, /\[field:[\s\S]*?\/]/, /{\/dede:[\s\S]*?}/, /<\?[\s\S]*?\?>/],
	                    ignoreCustomComments: [/<!--[\s]{dede:[\s\S]*?}[\s]-->/],
	                    /* 忽略dedecms {dede: ...} [field:.../]  {/dede:..} <? ... ?>  标签*/
	                    removeScriptTypeAttributes: true,
	                    /* 删除 type="text/javascript"  */
	                    removeStyleLinkTypeAttributes: true,
	                    /* 删除 type="text/css" */
	                    // removeComments: true,
	                    /*删除注释*/
	                    removeCommentsFromCDATA: true,
	                    /* 删除 script 和style标签内的HTML注释*/
	                    collapseWhitespace: true,
	                    /*压缩空白*/
	                    collapseBooleanAttributes: true,
	                    /*压缩布尔属性*/
	                    removeAttributeQuotes: true,
	                    /*删除属性引号*/
	                    removeRedundantAttributes: true,
	                    /*删除冗余属性*/
	                    useShortDoctype: true,
	                    /*使用短文档类型声明*/
	                    removeEmptyAttributes: true,
	                    /*删除空属性*/
	                   // removeEmptyElements: true,
	                    /*删除空元素*/
	                    removeOptionalTags: true,
	                    /*删除可选标签*/
	                    keepClosingSlash: true,
	                    /*保持反斜杠*/
	                    includeAutoGeneratedTags: true,
	                    /*  */
	                    collapseInlineTagWhitespace: true,
	                    /* display:inline 属性不间隙 */
	                    html5: true,
	                    report: 'gzip'
	                },
	                html: {
	                    files: [{
	                        expand: true,
	                        cwd: 'html/',
	                        src: ['**/*.htm'],
	                        dest: 'opt_html/'
	                    }]
	                }
	            },

            autoprefixer: {
    options: {
      // Task-specific options go here.
       browserslist:['last 2 versions','chrome','ie'],
       map:true,
       safe: true,
    },
    single_file: {
      // Target-specific file lists and/or options go here.
       src:'css/*.css',
       dest:'opt_css/*.css',
           },

    mutiple_files: {
      // Target-specific file lists and/or options go here.
        expand:true,
        flatten: true,//是否取代原先文件名
       src:'css/*.css',
       dest:'opt_css/',
           },

  },

	            /************     HTML 文件处理     ************/
	            /************     监控文件变化     ************/
	            watch: {
	                /* 监控文件变化并执行相应任务 */
	                img: {
	                    files: ['img/*.{png,jpg,jpeg}'],
	                    options: {
	                        livereload: true
	                    }
	                },
	                css: {
	                    options: {
	                        event: ['changed', 'added'],
	                        livereload: true
	                    },
	                    files: ['css/*.css']
	                },
	                js: {
	                    options: {
	                        livereload: true
	                    },
	                    files: ['js/*.js']
	                },
	                html: {
	                    options: {
	                        livereload: true
	                    },
	                    files: ['html/*.html']
	                }
	            }
	        });
	        /************     监控文件变化     ************/
	        /************     加载frunt模块     ************/
	        grunt.loadNpmTasks('grunt-contrib-csslint');
	        grunt.loadNpmTasks('grunt-contrib-cssmin');
	        grunt.loadNpmTasks('grunt-contrib-sass');
	        grunt.loadNpmTasks('grunt-contrib-jshint');
	        grunt.loadNpmTasks('grunt-contrib-uglify');
	        grunt.loadNpmTasks('grunt-contrib-imagemin');
	        grunt.loadNpmTasks('grunt-contrib-htmlmin');
	        grunt.loadNpmTasks('grunt-autoprefixer');
	        /************     加载frunt模块     ************/
	        /************    注册frunt 任务    ************/
	        grunt.loadNpmTasks('grunt-contrib-concat');
	        grunt.registerTask('check_gf', ['jshint']);
	         grunt.registerTask('prefixer', ['autoprefixer:mutiple_files']);
	        //grunt.loadNpmTasks('grunt-contrib-watch');
	        grunt.registerTask('default', ['csslint', 'cssmin', 'jshint', 'uglify:minjs', 'imagemin', 'htmlmin']);
	        grunt.registerTask('uncss', ['uncss']);
	        grunt.registerTask('check_css', ['csslint']);
	        grunt.registerTask('css', ['cssmin', 'concat:css']);
	        grunt.registerTask('scss', ['sass']);
	        grunt.registerTask('image', ['imagemin']);
	        grunt.registerTask('html', ['htmlmin']);
	        grunt.registerTask('js', ['concat:js', 'uglify:minjs']);
	        grunt.registerTask('compress_js', ['uglify:minjs']);
	        grunt.registerTask('compress_css', ['cssmin']);
	        // 定义默认任务
	        // grunt.registerTask('dev', ['csslint', 'jshint']);
	        // grunt.registerTask('dest', ['imagemin', 'concat:css', 'cssmin', 'uglify:minjs']);
	        /************    注册frunt 任务    ************/
	    };


知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:柴宏俊»