Grunt

  • Grunt介绍

中文主页 : http://www.gruntjs.net
是一套前端 自动化构建 工具,一个基于nodeJs的命令行工具
它是一个 任务运行器 , 配合其丰富强大的插件
常用功能:
----------合并文件(js/css)
----------压缩文件(js/css)
----------语法检查(js)
----------less/sass预编译处理
----------其它...

  • 安装nodejs, 查看版本

node -v

  • 创建一个简单的应用grunt_test
|- build----------构建生成的文件所在的文件夹
    |- src------------源码文件夹 
        |- js---------------js源文件夹
        |- css--------------css源文件夹
|- index.html-----页面文件
|- Gruntfile.js---grunt配置文件(注意首字母大写)
|- package.json---项目包配置文件
  • 全局安装 grunt-cli

cnpm install -g grunt-cli

  • 安装grunt

cnpm install grunt --save-dev

  • 配置文件: Gruntfile.js 此配置文件本质就是一个node函数类型模块 配置编码包含3步:

1. 初始化插件配置
2. 加载插件任务
3. 注册构建任务

基本编码:
module.exports = function(grunt){
    // 1\. 初始化插件配置
    grunt.initConfig({
         //主要编码处
    });
    // 2\. 加载插件任务
    // grunt.loadNpmTasks('grunt-contrib-concat');
    // 3\. 注册构建任务
    grunt.registerTask('default', []);
};

命令: grunt //提示成功, 但没有任何效果(还没有使用插件定义任务)

  • Grunt插件介绍

grunt官网的插件列表页面 http://www.gruntjs.net/plugins
插件分类:
--------- grunt团队贡献的插件 : 插件名大都以contrib-开头
--------- 第三方提供的插件 : 大都不以contrib-开头
常用的插件:
--------- grunt-contrib-clean—— 清除文件(打包处理生成的)
--------- grunt-contrib-concat——合并多个文件的代码到一个文件中
--------- grunt-contrib-uglify——压缩js文件
--------- grunt-contrib-jshint——javascript语法错误检查
--------- grunt-contrib-cssmin——压缩/合并css文件
--------- grunt-contrib-htmlmin——压缩html文件
--------- grunt-contrib-imagemin——压缩图片文件(无损)
--------- grunt-contrib-copy—— 复制文件、文件夹
--------- grunt-contrib-requirejs**—— 合并压缩requirejs管理的所有js模块文件
--------- grunt-contrib-watch—— 实时监控文件变化、调用相应的任务重新执行

  • 合并js: 使用concat插件

下载插件 cnpm install grunt-contrib-concat --save-dev

`1. 编码:`
//  src/js/test1.js
(function () {
    function add(num1, num2) {
        return num1 + num2;
    }
    console.log(add(10, 20));
})();

//  src/js/test2.js

(function () {
    var arr = [2,3,4].map(function (item, index) {
        return item+1;
    });
    console.log(arr);
})();

` 2. 配置: Gruntfile.js`

module.exports = function(grunt) {
    // 配置任务
    grunt.initConfig({
        //任务名
        concat: {
            //可选项配置
            options: {
                //使用;连接合并
                separator: ';',
            },
            dist: {
                //合并哪些js文件,也可以指定具体合并文件['src/1.js','src/2.js']
                src: ['src/js/*.js'],
                //输出地址
                dest: 'build/js/build.js'
            }
        }
    });
    // 加载包含 "concat" 任务的插件。
    grunt.loadNpmTasks('grunt-contrib-concat');
};

`3. 执行命令: grunt concat   //会在build下生成一个built.js`
  • 压缩js: 使用uglify插件

下载插件 cnpm install grunt-contrib-uglify --save-dev
注意: 压缩任务执行的结果, 会将虽然声明过,但从没使用的函数/变量 剔除掉

` 1. 配置: Gruntfile.js`

module.exports = function(grunt) {
    // 配置任务
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
            options: {
                banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
                '<%= grunt.template.today("yyyy-mm-dd") %> */'
            },
            build_min: {
                files: {
                    'build/js/build.min.js': ['build/js/build.js']
                }
            }
        }
    });
    // 加载包含 "uglify" 任务的插件。
    grunt.loadNpmTasks('grunt-contrib-uglify');
};

`3. 执行命令: grunt uglify  会将build/js/build.js 压缩为 build/js/build.min.js`
  • 默认任务: 注册任务队列 , 执行 grunt命令 , 自动 同步 执行队列任务

同步执行 就要注意一下,任务的顺序了, 仔细想想下一个任务依赖不依赖上一个任务的结果

module.exports = function(grunt) {
  // 配置任务
  grunt.initConfig({
   ............
  });
  // 加载插件。
  grunt.loadNpmTasks('........');
  // 加载包含 "concat" 任务的插件。
  //grunt.loadNpmTasks('grunt-contrib-concat');

  // 命令行执行 grunt  执行默认的任务列表。
  grunt.registerTask('default', ['concat','uglify']);

};
  • js语法检查: 使用jshint插件

下载插件 cnpm install grunt-contrib-jshint --save-dev

` 1. 新建 .jshintrc文件`
{
  "curly": true,
  "eqeqeq": true,
  "eqnull": true,
  "expr" : true,
  "immed": true,
  "newcap": true,
  "noempty": true,
  "noarg": true,
  "regexp": true,
  "browser": true,
  "devel": true,
  "node": true,
  "boss": false,
  
  //不能使用未定义的变量
  "undef": true,
  //语句后面必须有分号
  "asi": false,
  //预定义不检查的全局变量 ,注:使用一些外部引入插件的变量,但是我们项目里没有这个变量,这里可以屏蔽掉错误
  "predef": [ "define", "BMap", "angular", "BMAP_STATUS_SUCCESS"] 
}
` 2.  Gruntfile.js`
//配置任务
jshint : {
  options: {
    jshintrc : '.jshintrc' //指定配置文件,在根目录可以不写路径
  },
  build : ['Gruntfile.js', 'src/js/*.js'] //指定检查的文件
}
//加载插件
grunt.loadNpmTasks('grunt-contrib-jshint');
//注册任务
grunt.registerTask('default', ['concat', 'uglify', 'jshint']);
` 3. 执行 grunt 命名`
  • CSS压缩&合并 使用 cssmin插件

下载插件 cnpm install grunt-contrib-cssmin --save-dev

` 1. 编码`
// src/css/1.css
#box1 {
  width: 100px;
  height: 100px;
  background: red;
}
// src/css/2.css
#box2 {
  width: 200px;
  height: 200px;
  background: blue;
}
// index.html
<link rel="stylesheet" href="build/css/output.min.css">
<div id="box1"></div>
<div id="box2"></div>

` 2. Gruntfile.js`
// 配置任务
cssmin:{
  options: {
    shorthandCompacting: false,
    roundingPrecision: -1
  },
  build: {
    files: {
        'build/css/build.min.css': ['src/css/*.css']
    }
  }
}
// 加载插件
grunt.loadNpmTasks('grunt-contrib-cssmin');
// 注册任务
grunt.registerTask('default', ['concat', 'uglify', 'jshint', 'cssmin']);

` 3. 执行命令`
grunt 
  • 使用watch插件(真正实现自动化 )

下载插件 cnpm install grunt-contrib-watch --save-dev

` 1. Gruntfile.js `
// 配置任务
watch : {
  scripts : {
    files : ['src/js/*.js', 'src/css/*.css'],
    tasks : ['concat', 'jshint', 'uglify', 'cssmin'],
    //true:全量更新 不管更新的是什么 js css文件的任务全部更新一遍 false:变量更新 表示只更新当前文件类型的任务
    options : {spawn : false}  
  }
}

//加载插件
grunt.loadNpmTasks('grunt-contrib-watch');
//注册任务
grunt.registerTask('default', ['concat', 'uglify', 'jshint', 'watch']);
//执行命名 监控文件变化, 自动构建 
grunt

2. 改进
//开发完毕执行 grunt命令 生成项目 提交代码
grunt.registerTask('default', ['concat', 'uglify', 'jshint']); 
//开发的时候 使用 grunt myWatch , 实时监控 变化 ,自动构建项目
grunt.registerTask('myWatch', ['default','watch']);
  • 使用Sass插件

下载插件 cnpm install grunt-contrib-sass --save-dev

` 1. 编码`
// src/test.scss
$baseWidth :50px;
$baseWidth :100px !default;

#box1{
    width: $baseWidth;
}
` 2 . Gruntfile.js`
// 配置任务
sass: {
    dist: {
        files: [{
            expand: true,
            cwd: 'src/css',
            src: ['*.scss'],
            dest: 'src/css',
            ext: '.css'
        }]
    }
}
//加载插件
grunt.loadNpmTasks('grunt-contrib-sass');
// 修改watch 监听任务顺序,将sass的任务处理 放在cssmin任务之前
watch : {
      scripts : {
        files : ['src/js/*.js', 'src/css/*.css','src/css/*.scss'],
        tasks : ['concat', 'jshint', 'uglify','sass', 'cssmin'],
        //true:全量更新 不管更新的是什么 js css文件的任务全部更新一遍 false:变量更新 表示只更新当前文件类型的任务
        options : {spawn : false}  
      }
}
//修改 registerTask的默认任务队列, 将sass的任务处理 放在cssmin任务之前
grunt.registerTask('default', ['concat','uglify','jshint','sass','cssmin']);
//执行监听
grunt myWatch
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345