用Grunt搭建自动化Web开发环境

安装 grunt

npm install grunt --save-dev

将使用npm下载grunt插件,它们将保存到项目根目录下的 node_components 目录下。

后面的 --save-dev 参数是说,把这个插件信息,同时添加到 package.json 的devDependencies 中:

"devDependencies": {
  "grunt": "~0.4.5"
}

由于grunt仅在开发阶段使用,所以使用 --save-dev 。如果是运行时使用的,则用--save

安装 grunt-cli

上面安装的 grunt 并不包含命令行工具,我们还需安装相应的 grunt-cli ,才能在命令行中调用 grunt 命令:

npm install grunt-cli -g

后面的 -g 是说,把 grunt-cli 安装成全局工具,以便在任意目录下使用。

安装后,输入:

grunt --version

我这里显示为:

grunt-cli v0.1.13
grunt v0.4.5

在比较少的情况下,可能提示找不到grunt,则需要根据安装grunt-cli时的提示信息,把相应的路径添加到 PATH 中:

echo PATH=$PATH:/your/path/to/grunt >> ~/.bashrc
source ~/.bashrc

 

为grunt创建配置文件Gruntfile.js

安装grunt-init

npm install grunt-init -g

下载grunt模板

git clone https://github.com/gruntjs/grunt-init-gruntfile.git ~/.grunt-init/gruntfile

生成Gruntfile

grunt-init gruntfile

根据需要回答问题,或者使用默认值,将得到以下 Gruntfile.js 文件:

/*global module:false*/
module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['lib/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      }
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      dist: {
        src: '<%= concat.dist.dest %>',
        dest: 'dist/<%= pkg.name %>.min.js'
      }
    },
    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        unused: true,
        boss: true,
        eqnull: true,
        browser: true,
        globals: {
          jQuery: true
        }
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      lib_test: {
        src: ['lib/**/*.js', 'test/**/*.js']
      }
    },
    qunit: {
      files: ['test/**/*.html']
    },
    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      lib_test: {
        files: '<%= jshint.lib_test.src %>',
        tasks: ['jshint:lib_test', 'qunit']
      }
    }
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Default task.
  grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);

};

它里面已经包含了一些常用的插件,比如 grunt-contrib-jshint 等,我们可根据需要删减一些用不上的。

它同时还会在 package.json 里添加上这些插件的依赖:

"grunt-contrib-concat": "~0.4.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-qunit": "~0.5.2",
"grunt-contrib-uglify": "~0.5.0",
"grunt-contrib-watch": "~0.6.1"

这些插件还未下载,如果需要,可以运行:

npm install

把它们下载到本地。

具体配置Gruntfile文件(以concat-合并插件为例)

module.exports = function(grunt){
    //初始化grunt配置
    grunt.initConfig({

        // 导入 package.json 的信息并存到pkg中
        pkg: grunt.file.readJSON('package.json'),

        //告诉grunt我们将怎么使用插件(此处key要与下面注入的插件同名)
        //concat插件的配置信息
        concat: {
            options: {
                stripBanners: true,
                // 此处定义的banner注释将插入到输出文件的顶部
                banner: '/*! <%= pkg.name %> <%= pkg.verson %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
            },
            // 此处是自定义事件,配置concat的输出结果
            cssConcat: {
                //将style1 2合并到concat文件夹下,以name-verson(文件名-版本号)的方式命名
                src: ['src/css/css1.css', 'src/css/css2.css'],
                dest: 'src/css/concat/<%= pkg.name %> - <%= pkg.verson %>.css'
            },
            jsConcat: {
                src: 'src/js/*.js',
                dest: 'src/js/concat/<%= pkg.name %> - <%= pkg.verson %>.js'
            }
        }
    });

    //告诉grunt我们将使用什么插件
    grunt.loadNpmTasks('grunt-contrib-concat');

    //告诉grunt当我们在命令行中输入grunt时需要做些什么
    grunt.registerTask('default', ['concat']);
};

在控制台运行 grunt 命令,运行之后目录如下,可以看到css1 css2被合并输出到一个concat文件夹中:

压缩插件实例

使用 cssmin/uglify 插件对合并后的css/js 文件进行压缩,并将压缩后的文件存入 dist 目录下。请注意先下载对应的依赖包。

module.exports = function(grunt){
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: {...},

        // cssmin插件的配置信息 - 压缩CSS代码
        cssmin: {
            options: {
                stripBanners: true,
                banner: '/*! <%= pkg.name %> <%= pkg.verson %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
            },
            compress: {
                src: 'src/css/concat/<%= pkg.name %> - <%= pkg.verson %>.css',
                dest: 'dist/css/<%= pkg.name %> - <%= pkg.verson %>.min.css'
            }
        },
        // uglify的插件配置信息 - 压缩js代码
        uglify: {
            options: {
                stripBanners: true,
                banner: '/*! <%= pkg.name %> <%= pkg.verson %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
            },
            compress: {
                src: 'src/js/concat/<%= pkg.name %> - <%= pkg.verson %>.js',
                dest: 'dist/js/<%= pkg.name %> - <%= pkg.verson %>.min.js'
            }
        }
    });

    // 告诉grunt我们将使用什么插件
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    // 注意先合并再压缩,同时引入全部依赖
    grunt.registerTask('default', ['concat', 'cssmin', 'uglify']);
};    

检查语法错误实例

在使用 csslint 与 jshin 插件检查语法错误时,要现在工程根目录下建两个文件 .csslintrc 和 .jshintrc 。它们内部写入了对语法检查项的配置内容,详细代码请google或参考github上各大项目。

在Gruntfile.js中配置好对应信息。当故意设置语法错误之后,输出如下图:

使用watch进行自动化配置

引入 watch 插件,将src目录下文件加入监控列表,此后的每次改动grunt都会自动进行纠正、合并、压缩,无需再运行grunt指令。

事例代码及更多插件请见grunt插件列表

posted @ 2016-03-18 09:31  潘诗瑶  阅读(145)  评论(0)    收藏  举报