基于Node.js的自动化构建工具Grunt.js

Java世界里的Maven提供了强大的包依赖管理和构建生命周期管理。在JavaScript的世界里,随着Node.js的流行,JavaScript原生的构建工具已经成为可能。

\

Grunt.js是基于Node.js的自动化任务运行器。Grunt.js结合NPM的包依赖管理,完全可以媲美Maven。Grunt.js天然适合前端应用程序的构建——不仅限于JavaScript项目,同样可以用于其他语言的应用程序构建。越来越多的JavaScript项目已经在使用Grunt,其中最大的使用者包括著名的jQuery项目。

\

Grunt的生态系统在迅速的成长,目前已经有上百种插件发布在NPM上可供选择。同时,任何人都可以方便的发布自己的插件到NPM上供其他人使用。

\

Grunt没有像Maven那样强调构建的生命周期,各种任务的执行顺序可以随意配置。Grunt本身仅是一个执行器,大量的功能都存在于NPM管理的插件中。特别是以grunt-contrib-开头的核心插件,覆盖了大部分的核心功能,比如handlebars,jade,less,compass,jshint,jasmine,clean,concat,minify,copy,uglify,watch,minify,uglify等。

\

通过提供通用的接口以进行代码规范检验(Lint)、合并、压缩、测试及版本控制等任务,Grunt使入门门槛大大降低了。

\

安装

\

Grunt目前的最新版本为v0.4版。相比v0.3版,Grunt本身不再作为一个整体全局模块安装,而是分为了三个部分:grunt,grunt-cli,grunt-init。

\

grunt-cli用于命令行启动Grunt,必须作为全局模块安装:

\

npm install -g grunt-cli

\

grunt-init是可选的,用于以命令行新建Grunt项目模板,必须作为全局模块来安装:

\

npm install -g grunt-init

\

Grunt核心作为项目或插件的依赖包而单独存在,避免由于不同的插件依赖的Grunt版本不同而造成的冲突。

\

新建项目工程

\

在命令行中执行  grunt init

\

无论新建项目是应用程序还是一个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: '/*! \u0026lt;%= pkg.name %\u0026gt; \u0026lt;%= grunt.template.today(\"yyyy-mm-dd\") %\u0026gt; */\'\\      },\\      build: {\\        src: 'src/\u0026lt;%= pkg.name %\u0026gt;.js',\\        dest: 'build/\u0026lt;%= pkg.name %\u0026gt;.min.js'\\      }\\    }\\  });\\\  // 加载\"uglify\"插件..\\  grunt.loadNpmTasks('grunt-contrib-uglify');\\\  // 注册默认任务.\\  grunt.registerTask('default', ['uglify']);\\\};\
\

可以看到,它就是一个标准的Node.js模块定义。

\
  1. \

    插件配置:形如JSON对象的配置信息,包括定义文件操作的源与目标,标志变量等。Grunt还提供了一些模板变量用于插入常用的信息,如日期时间等。

    \ \
  2. \

    加载插件:通过grunt.loadNpmTask(),显式地加载外部Grunt插件。

    \ \
  3. \

    注册自定义任务。用法见下文“自定义任务”。可以注册任意的任务链,但至少注册一个默认任务链。

    \ \

运行

\

进入项目的根目录,在命令行执行grunt 即可根据配置文件来执行所有的自动化任务。

\
\$ grunt\\Running \"jshint:gruntfile\" (jshint) task\\1 file lint free.\\ \\Running \"jshint:src\" (jshint) task\\1 file lint free.\\ \\Running \"uglify:dist\" (uglify) task\\File \"dist/ba-tiny-pubsub.min.js\" created.\\Uncompressed size: 389 bytes.\\Compressed size: 119 bytes gzipped (185 bytes minified).\\ \\Done, without errors.\\\$\
\

也可以选择性地执行某些任务,甚至给不同的插件附加命令行参数:

\

例如,只执行clean插件的dist子任务和jasmine插件的所有任务:

\

grunt clean:dist jasmine

\

流行的插件

\

v0.4版以后,各种常用插件基本都归入了 grunt-contrib-xxx系列。下面介绍几个比较常用的插件:

\
  • \

    grunt-contrib-clean: 用于清理指定文件(夹),一般是构建之前或之后进行

    \ \
  • \

    grunt-contrib-coffee: 将CoffeeScript编译为JavaScript

    \ \
  • \

    grunt-contrib-compass: 调用Compass工具生成CSS文件

    \ \
  • \

    grunt-contrib-concat: 连接源文件,减少HTTP请求

    \ \
  • \

    grunt-contrib-copy: 复制文件(夹)

    \ \
  • \

    grunt-contrib-handlebars: 将handlebars模板预编译为JST文件,提高运行时性能

    \ \
  • \

    grunt-contrib-jasmine: 借助Jasmine在PhantomsJS中运行单元测试,结合grunt-template-jasmine-istanbul,还能实现单元测试覆盖率计算

    \ \
  • \

    grunt-contrib-jshint: JS代码质量检查工具,类似jsLint

    \ \
  • \

    grunt-contrib-watch: 监视磁盘文件,一旦更改就会重新运行指定的任务,例如使http服务器重新加载源文件

    \ \
  • \

    grunt-contrib-ugligy: 压缩JS源文件,提高运行时性能

    \ \

自定义任务

\

利用Grunt的API可以很方便的创建自定义任务和插件。两种方式所用到的API完全一致,只不过自定义任务在写在项目的gruntfile.js中,而插件可以自主发布。

\

任务分为两种:

\
  • \

    grunt.registerTask():以JS函数的形式定义的一个独立的任务,可以从命令行传入参数、调用Grunt API、 或者仅仅是作为别名(alias),链式地调用其他任务。

    \ \
  • \

    grunt.registerMultiTask():与registerTask()函数不同的是,同一任务可以同时存在多组配置目标(target),Grunt会自动地遍历读取每组配置目标分别执行,也可以指定仅以某个配置来单独执行任务。这对于文件操作任务比较常用。例如要使用清理文件的clean插件,可能会有两组配置,分别用于清理打包文件夹和清理单元测试临时文件夹。此外,jshint,concat,uglify等也都是MuitiTask类型。

    \ \

API扩展

\

无论是自定义任务还是创建独立的Grunt插件,都少不了要用到Grunt提供的API。其中一些是对Node.js功能的扩展,另一些是满足Grunt的特殊需要:

\
  1. \

    grunt.config: 读取和管理gruntfile中的配置信息

    \ \
  2. \

    grunt.event: 自定义事件

    \ \
  3. \

    grunt.fail: 用于异常处理时发出警告或强制终止任务

    \ \
  4. \

    grunt.file: 用于磁盘文件管理的扩展函数,包括read,write,copy,delete,mkdir,expand,exist,path等

    \ \
  5. \

    grunt.log: Grunt自有的log功能

    \ \
  6. \

    grunt.option: 用于从命令行中读取参数

    \ \
  7. \

    grunt.task: 用于注册自定义任务和加载外部任务

    \ \
  8. \

    grunt.template: 处理gruntfile中的模板变量,以及提供了常用的日期模板辅助(helper)函数,包括template.data,template.today

    \ \
  9. \

    grunt.util:  各种公用工具函数,以及集成了各种外部库,包括Lo-Dash,Async,Hook等

    \ \

小结

\

本文介绍了基于Node.js的自动化构建工具Grunt.js,展示了其基本组成、安装步骤,配置文件示例以及运行示例,并且列出了流行的Grunt插件以及其API扩展接口。 

\

作者简介:

\

申健,在跨国企业从事8年以上的研发和管理工作,涉及电信、金融、互联网等领域,拥有丰富的移动应用程序和面向服务分布式系统的项目经验。2007年开始接触敏捷开发。对大型组织(500人以上)的敏捷转型,以及敏捷工程实践的落地运用具有丰富的经验。拥有CSP, CSM。擅长面向服务(SOA)的分布式架构分析,以及移动应用的前后端整体解决方案。天津软件沙龙和敏捷之旅天津站等活动的组织者。

\

感谢田永强对本文的审校。

\

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值