用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插件列表。

浙公网安备 33010602011771号