Java世界里的Maven提供了强大的包依赖管理和构建生命周期管理。在JavaScript的世界里,随着Node.js的流行,JavaScript原生的构建工具已经成为可能。
Grunt.js是基于Node.js的自动化任务运行器。Grunt.js结合NPM的包依赖管理,完全可以媲美Maven。Grunt.js天然适合前端应用程序的构建——不仅限于JavaScript项目,同样可以用于其他语言的应用程序构建。越来越多的JavaScript项目已经在使用Grunt,其中最大的使用者包括著名的jQuery项目。
Grunt的生态系统在迅速的成长,目前已经有上百种插件发布在NPM上可供选择。同时,任何人都可以方便的发布自己的插件到NPM上供其他人使用。
安装
Grunt目前的最新版本为v0.4版。相比v0.3版,Grunt本身不再作为一个整体全局模块安装,而是分为了三个部分:grunt,grunt-cli,grunt-init。
grunt-cli用于命令行启动Grunt,必须作为全局模块安装:
npminstall-ggrunt-cli
grunt-init是可选的,用于以命令行新建Grunt项目模板,必须作为全局模块来安装:
npminstall-ggrunt-init
Grunt核心作为项目或插件的依赖包而单独存在,避免由于不同的插件依赖的Grunt版本不同而造成的冲突。
新建项目工程
在命令行中执行gruntinit
无论新建项目是应用程序还是一个Grunt插件,Grunt生成的工程都是一个标准的NPM模块。
新工程目录下有两个文件非常重要:
package.json:NPM的发布配置文件,包含了包依赖信息和项目工程的元数据。熟悉Node.js的读者应该不陌生。
gruntfile.js:Grunt配置文件,用于配置或定义Grunt任务,以及加载Grunt插件等。
Grunt任务配置
所有的任务配置都存在gruntfile.js中。作为JavaScript源文件,其配置信息以JSON对象的方式来存放,并可以使用JS函数来动态生成,比Maven的XML配置方式更加简洁和富有灵活性。一份典型的gruntfile如下:
module.exports=function(grunt){//项目配置信息.grunt.initConfig({pkg:grunt.file.readJSON(‘package.json’),uglify:{options:{banner:‘/*!%=pkg.name%%=grunt.template.today(“yyyy-mm-dd”)%*/n’},build:{src:‘src/%=pkg.name%.js’,dest:‘build/%=pkg.name%.min.js’}}});//加载”uglify”插件..grunt.loadNpmTasks(‘grunt-contrib-uglify’);//注册默认任务.grunt.registerTask(‘default’,[‘uglify’]);};
可以看到,它就是一个标准的Node.js模块定义。
插件配置:形如JSON对象的配置信息,包括定义文件操作的源与目标,标志变量等。Grunt还提供了一些模板变量用于插入常用的信息,如日期时间等。
加载插件:通过grunt.loadNpmTask(),显式地加载外部Grunt插件。
注册自定义任务。用法见下文“自定义任务”。可以注册任意的任务链,但至少注册一个默认任务链。
运行
进入项目的根目录,在命令行执行grunt即可根据配置文件来执行所有的自动化任务。
gruntRunning“jshint:gruntfile”(jshint)task1filelintfree.Running“jshint:src”(jshint)task1filelintfree.Running“uglify:dist”(uglify)taskFile“dist/ba-tiny-pubsub.min.js”created.Un 也可以选择性地执行某些任务,甚至给不同的插件附加命令行参数:
例如,只执行clean插件的dist子任务和jasmine插件的所有任务:
gruntclean:distjasmine
流行的插件
v0.4版以后,各种常用插件基本都归入了grunt-contrib-xxx系列。下面介绍几个比较常用的插件:
grunt-contrib-clean:用于清理指定文件(夹),一般是构建之前或之后进行grunt-contrib-coffee:将CoffeeScript编译为JavaScriptgrunt-contrib- 自定义任务
利用Grunt的API可以很方便的创建自定义任务和插件。两种方式所用到的API完全一致,只不过自定义任务在写在项目的gruntfile.js中,而插件可以自主发布。
任务分为两种:
-grunt.registerTask():以JS函数的形式定义的一个独立的任务,可以从命令行传入参数、调用GruntAPI、或者仅仅是作为别名(alias),链式地调用其他任务。
-grunt.registerMultiTask():与registerTask()函数不同的是,同一任务可以同时存在多组配置目标(target),Grunt会自动地遍历读取每组配置目标分别执行,也可以指定仅以某个配置来单独执行任务。这对于文件操作任务比较常用。例如要使用清理文件的clean插件,可能会有两组配置,分别用于清理打包文件夹和清理单元测试临时文件夹。此外,jshint,concat,uglify等也都是MuitiTask类型。
API扩展
无论是自定义任务还是创建独立的Grunt插件,都少不了要用到Grunt提供的API。其中一些是对Node.js功能的扩展,另一些是满足Grunt的特殊需要:
grunt.config:读取和管理gruntfile中的配置信息grunt.event:自定义事件grunt.fail:用于异常处理时发出警告或强制终止任务grunt.file:用于磁盘文件管理的扩展函数,包括read,write,copy,delete,mkdir,expand,exist,path等grunt.log:Grunt自有的log功能grunt.option:用于从命令行中读取参数grunt.task:用于注册自定义任务和加载外部任务grunt.template:处理gruntfile中的模板变量,以及提供了常用的日期模板辅助(helper)函数,包括template.data,template.todaygrunt.util:各种公用工具函数,以及集成了各种外部库,包括Lo-Dash,Async,Hook等
小结本文介绍了基于Node.js的自动化构建工具Grunt.js,展示了其基本组成、安装步骤,配置文件示例以及运行示例,并且列出了流行的Grunt插件以及其API扩展接口。