前端js和css的压缩合并之grunt

关于css和js压缩和合并的方法,记得我在前端面试题目中有写道。方法很多,今天主要介绍grunt方法。

使用前提

grunt是基于node的,要在你电脑上使用grunt,电脑上必须已安装node环境。具体node环境的安装和搭建。centos请看,windows安装相对简单,下载安装包安装就可以了。关于mac的安装,后面有时间在详细介绍。

一、新建package.json

package.json放在根目录下,它包含了该项目的一些元信息,如项目名称、描述、版本号,插件等。

{
  "name": "haorooms.com",
  "version": "v0.1.0",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-jshint": "~0.10.0",
    "grunt-contrib-nodeunit": "~0.4.1",
    "grunt-contrib-uglify": "~0.5.0",
    "grunt-contrib-concat": "~0.5.1",
    "grunt-contrib-cssmin": "~0.12.3",
    "grunt-htmlhint": "~0.9.2"
  }
}

grunt-contrib-jshint(js语法检查)、grunt-contrib-concat(js合并)、grunt-contrib-uglify(采用UglifyJS压缩js)、grunt-contrib-cssmin(Css压缩合并)、grunt-htmlhint(html语法验查),以上都是常用的插件。
更多插件,请访问:http://gruntjs.com/plugins

二、插件安装

安装:uglify

npm install grunt-contrib-uglify

安装concat

npm install grunt-contrib-concat

安装:cssmin

npm install grunt-contrib-cssmin

插件安装完成后,查看根目录,会发现node_modules目录,包含了相应的插件目录。

三、新建Gruntfile.js

Gruntfile.js由以下内容组成
1、wrapper函数,结构如下,这是Node.js的典型写法,使用exports公开API

 module.exports = function(grunt) { 
    // Do grunt-related things in here 
};

2、项目和任务配置
3、载入grunt插件和任务
4、定制执行任务
例如:

module.exports = function(grunt) {
 //配置参数
 grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
        options: {
            separator: ';',
            stripBanners: true
        },
        dist: {
            src: [
                "js/config.js",
                "js/smeite.js",
                "js/index.js"
            ],
            dest: "assets/js/default.js"
        }
    },
    uglify: {
        options: {
        },
        dist: {
            files: {
                'assets/js/default.min.js': 'assets/js/default.js'
            }
        }
    },
    cssmin: {
        options: {
            keepSpecialComments: 0
        },
        compress: {
            files: {
                'assets/css/default.css': [
                    "css/global.css",
                    "css/pops.css",
                    "css/index.css"
                ]
            }
        }
    }
 });

 //载入concat和uglify插件,分别对于合并和压缩
 grunt.loadNpmTasks('grunt-contrib-concat');
 grunt.loadNpmTasks('grunt-contrib-uglify');
 grunt.loadNpmTasks('grunt-contrib-cssmin');

 //注册任务
 grunt.registerTask('default', ['concat', 'uglify', 'cssmin']);
}

也可以单独压缩js和css,不进行合并,例如:

module.exports = function (grunt) {

    // 构建任务配置
    grunt.initConfig({

        //读取package.json的内容,形成个json数据
        pkg: grunt.file.readJSON('package.json'),

        //压缩js
        uglify: {
            //文件头部输出信息
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
            },
            my_target: {
                files: [
                    {
                        expand: true,
                        //相对路径
                        cwd: 'js/',
                        src: '*.js',
                       //src: ['**/*.js', '!**/*.min.js'],  //不包含某个js,某个文件夹下的js
                        dest: 'dest/js/',
                        rename: function (dest, src) {  
                                  var folder = src.substring(0, src.lastIndexOf('/'));  
                                  var filename = src.substring(src.lastIndexOf('/'), src.length);  
                                  //  var filename=src;  
                                  filename = filename.substring(0, filename.lastIndexOf('.'));  
                                  var fileresult=dest + folder + filename + '.min.js';  
                                  grunt.log.writeln("现处理文件:"+src+"  处理后文件:"+fileresult);  

                                  return fileresult;  
                                  //return  filename + '.min.js';  
                              } 
                    }
                ]
            }
        },

        //压缩css
        cssmin: {
            //文件头部输出信息
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
                //美化代码
                beautify: {
                    //中文ascii化,非常有用!防止中文乱码的神配置
                    ascii_only: true
                }
            },
            my_target: {
                files: [
                    {
                        expand: true,
                        //相对路径
                        cwd: 'css/',
                        src: '*.css',
                        dest: 'dest/css/',
                        rename: function (dest, src) {  
                                var folder = src.substring(0, src.lastIndexOf('/'));  
                                var filename = src.substring(src.lastIndexOf('/'), src.length);  
                                //  var filename=src;  
                                filename = filename.substring(0, filename.lastIndexOf('.'));  
                                var fileresult=dest + folder + filename + '.min.css';  
                                grunt.log.writeln("现处理文件:"+src+"  处理后文件:"+fileresult);  

                                return fileresult;  
                              //return  filename + '.min.js';
                                }
                    }
                ]
            }
        }

    });

    // 加载指定插件任务
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');

    // 默认执行的任务
    grunt.registerTask('default', ['uglify', 'cssmin']);

};

grunt api文档:http://gruntjs.com/api/grunt
grunt.initConfig方法
用于模块配置,它接受一个对象作为参数。该对象的成员与使用的同名模块一一对应。
每个目标的具体设置,需要参考该模板的文档。就cssmin来讲,minify目标的参数具体含义如下:
expand:如果设为true,就表示下面文件名的占位符(即*号)都要扩展成具体的文件名。
cwd:需要处理的文件(input)所在的目录。
src:表示需要处理的文件。如果采用数组形式,数组的每一项就是一个文件名,可以使用通配符。
dest:表示处理后的文件名或所在目录。
ext:表示处理后的文件后缀名。
grunt常用函数说明:
grunt.initConfig:定义各种模块的参数,每一个成员项对应一个同名模块。
grunt.loadNpmTasks:加载完成任务所需的模块。
grunt.registerTask:定义具体的任务。第一个参数为任务名,第二个参数是一个数组, 表示该任务需要依次使用的模块。

命令行执行grunt任务

进入到项目根目录,敲:

grunt

就会按Gruntfile配置的文件进行压缩合并。
也可以单独执行,例执行js压缩命令:

grunt uglify

css压缩命令:

grunt cssmin

视频教程

视频教程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容