利用 Grunt (几乎)无痛地做前端开发 (一)

标签: 前端开发 grunt jade less nodejs | 发表时间:2012-11-30 14:49 | 作者:前端-qhwa
出处:http://www.aliued.cn

前言

如果你想开发一个js应用,甭管多简单,都要先创建整个宇宙

来看看我们的Javascript小宇宙:

  1. 确定如何根据需求、功能划分模块,如何将代码分成多个文件开发,合成一个发布
  2. 保证上一条的同时,使用 Coffeescript、SCSS/LESS 等技术
  3. 保证上2条的同时,想想怎么在浏览器的刷新后一切都最新
  4. 保证上3条的同时,想想怎么在开发、测试、生产、预发布环境中都OK
  5. 保证上4条的同时,进行TDD式的开发
  6. …这还是js, 我们还没有涉及到HTML

 

Grunt 可以将创建小宇宙的工作变得轻松很多。

初识 grunt

以一个jQuery插件的开发为例。 开始之前,让我们先安装Grunt.

首先需要 Nodejs环境,这里假设你已经安装好了 NodejsNPM.

然后安装 grunt :

  npm install grunt

命令行方式更适合前端开发。这里我都用命令行来进行操作,windows用户推荐用git-shell或者powershell.

第一招:快速搭建脚手架

Grunt 已经安装好了,第一步就是利用grunt快速搭建脚手架出来。所谓的脚手架,就是指包含了目录结构和初始的一些功能,测试文件的一个环境。我们来搭建一个jquery插件的脚手架:

  grunt init:jquery

这时grunt会问你一些问题,比如项目名称, git地址,作者等等,比如:

initing

可以看到,grunt已经帮我们创建了一些经常出现的文件(README, LICENSE等), 单元测试也准备好了。

有些问题可以 配置一下默认回答,这样就不需要每次都重新输入了,只要敲回车就行。

第二招:TDD(测试驱动开发) 和 单元测试

现在我们就可以着手写grunt-demo-1这个插件了。假设我们这个插件的目的是让页面上*.alibaba.com域名下的a链接都带上一个图标。那么可以写一些简单的qunit用例。

首先在 test/grunt-demo-1.html准备好HTML用例:

      
...
<div id="qunit-fixture">
    <a href="#functional-link">#nogo</a>
    <a href="http://alibaba.com">grunt</a>
    <a href="http://china.alibaba.com">grunt</a>
    <a href="http://style.china.alibaba.com">grunt</a>
    <a href="http://q.pnq.cc">qhwa</a>
</div>
....

打开上一步grunt已经帮我们生成的 test/grunt-demo-1_test.js,写上我们自己的单元测试:

      
// file: test/grunt-demo_test.js
module('jQuery#ali-link', {
  setup: function() {
    this.elems = $('#qunit-fixture').children();
  }
});
test('is chainable', 1, function() {
  strictEqual(this.elems.alilink(), this.elems, 'should be chaninable');
});
test('can select', function() {
  equal( $('a:alilink', $('#qunit-fixture')).length, 3,
    'should select links with alibaba domain'
  );
});
test('add icon to alibaba links', function() {
  this.elems.alilink();
  this.elems.each(function(){
    var self = $(this);
    if( /^http:\/\/((.+)\.)?alibaba\.com/.test(this.href) ) {
      ok(self.hasClass('ali-link'));
    } else {
      ok(!self.hasClass('ali-link'));
    }
  });
});
...
view raw gistfile1.js This Gist brought to you by GitHub.

然后在命令行运行一下 grunt qunit

运行结果是这样的:

qunit fail

各种报错,对吧?不要紧,因为我们还没有开始写代码。接下来我们的目标就是写功能代码,让这个测试通过。

经过一番敲击键盘,以及运行了几次 grunt qunit,终于,激动人心时刻到来了,我们通过了所有的单元测试:

grunt qunit pass

最终的功能js如下:

      
// file: src/grunt-demo-1.js
(function($) {
  var ALI_LINK_REG = /^http:\/\/(.+\.)?alibaba\.com/;
  // Collection method.
  $.fn.alilink = function() {
    return this.each(function() {
      var self = $(this);
      if( isAliLink(this) ){
        self.addClass('ali-link');
      } else {
        self.removeClass('ali-link');
      }
    });
  };
  // Custom selector.
  $.expr[':'].alilink = function(elem) {
    return isAliLink(elem);
  };
  function isAliLink(el) {
    return /A/i.test(el.tagName) && ALI_LINK_REG.test(el.href);
  }
}(jQuery));
view raw gistfile1.js This Gist brought to you by GitHub.

想用jasmine? 当然可以了! 社区有  grunt-jasmine-runner

功能已经完成了,但是插件就完成了吗?非也!

有了单元测试,我们可以放心重构我们的代码,达到最好的可维护性。先让机器帮我们做个code review——也就是linting。

准备好了,就来看下一招:

第三招:利用 lint 提高代码质量

运行命令  grunt lint ,果然有报警:

grunt lint fail

嗯,我们的正则表达式写法不太好,那就来优化一下吧!

又经过一阵修改,我们的代码终于在  grunt lint 时没有报警了,不错!

运行一下  grunt qunit ,看到单元测试还能通过,功能正常,不错!

 

第四招:利用 watch 自动化

上面我们在重构和优化的时候,每次修改了功能js都要运行一遍 grunt qunitgrunt lint,grunt 可以帮我们做到一旦有修改,自动运行这两个命令,方便吧?

很简单,运行 grunt watch 就好了。然后试一下修改 src/ 下面的 js,就不需要手动去运行qunit和lint任务了。
watch 就是这样的一个任务,监测一些文件,都有更新的时候,自动运行需要的任务。

grunt watch

grunt 还自带了一些其他的任务,比如

  • 用来压缩js和css的 min 任务
  • 用来开启一个本地http服务器的  server 任务
  • 用来将几个文件合并成一个的  concat 任务

这些都是我们经常使用的任务。

小结

这一篇我们认识了 grunt ,下一篇将会看到 grunt 这种以任务为中心的设计,带来的强大扩展性。如果上面的例子已经让你感受到了无痛开发的乐趣,那么那些社区插件保证会让你更过瘾的!敬请期待本系列的第二篇—— 让 grunt 飞起来!

参考

grunt init

相关 [利用 grunt 几乎] 推荐:

利用 Grunt (几乎)无痛地做前端开发 (一)

- - 阿里巴巴(中国站)用户体验设计部博客
如果你想开发一个js应用,甭管多简单,都要先创建整个宇宙. 来看看我们的Javascript小宇宙:. 确定如何根据需求、功能划分模块,如何将代码分成多个文件开发,合成一个发布. 保证上一条的同时,使用 Coffeescript、SCSS/LESS 等技术. 保证上2条的同时,想想怎么在浏览器的刷新后一切都最新.

web开发利器之grunt

- - CSDN博客Web前端推荐文章
grunt不难,它主要依赖的是nodeJS的npm包管理器,和一个JSON及一个JS文件,先说说npm包管理器,玩过nodeJS的对它应该都很熟悉,在这里我们只需要安装nodeJS即可(新版的nodeJS基本都集成了npm),至于nodeJS的安装可以 点这里,这这篇文章就不做详细介绍,安装完后打开命令管理器(nodeJS安装完后的终端)输入:.

JavaScript 项目构建工具 Grunt 实践:安装和创建项目框架

- - 博客园_首页
Grunt 是一个基于任务的. JavaScript 项目命令行构建工具,运行于 Node.js 平台. Grunt 能够从模板快速创建项目,合并、压缩和校验 CSS & JS 文件,运行单元测试以及启动静态服务器.   推荐 Windows 用户使用 Git Shell 来进行命令行操作. 安装 Windows 桌面版 GitHub 的时候会自动安装 Git Shell.

六大关键几乎可以改变一切

- 山河之外 - 战隼的学习探索
很不错的一篇文章,我今年坚持的习惯都符合这6个要求,到目前进展还不错. 作者:托尼•施瓦茨(Tony Schwartz) 发表于:2011-03-30. “新年决心”几乎都是以失败告终的. 但是在我的公司The Energy Project,我们设计了一种经检验有效而持久的做出改变的方法,不管是对我自己的生活,还是对我们的客户来说,都很有效.

新药能治疗几乎所有病毒性感染

- 小天 - Solidot
绝大多数细菌性感染可用抗生素如青霉素治疗,然而抗生素药物对于病毒性感染如普通感冒、流行性感冒、出血热和埃博拉病毒等,毫无用处. 现在,MIT林肯实验室的研究人员设计出新的药物,能识别出被病毒感染的细胞,然后杀死细胞终止感染. 研究报告发表在PLoS One上. 研究人员测试了15种病毒,发现新药物能有效对付所有这些病毒——包括引起普通流感的鼻病毒,H1N1流感病毒,胃病毒,脊髓灰质炎病毒,登革热和出血热病毒.

Lenovo Q1 净利几乎加倍,Ultrabook 大战当然不缺席

- ArmadilloCommander - Engadget 中国版
今天天气不管怎样,想必在联想总部上空都是阳光普照的好日子,因为联想 Q1 的营收达到了 59.2 亿美元,比去年同期增加了 15%,而且更重要的,净利从去年的 5,490 万美元跳到了 1.08 亿美元,几乎多了一倍. 这背后的功臣,不意外的当然就是暴冲的笔电销量,和相对持平的竞争对手们比起来,确实是亮眼得多.

开启nginx cache后导致内存几乎100%问题

- - 开涛的博客
1、前些日子某服务被刷,每分钟达到上几百万请求;当时采用了nginx cache来解决的;但是因为某服务不能缓存太久,当时设置了5s,那么带来的问题就是产生大量小文件,而且很快就删除了. 会发现used是27G;但是通过top查看进程占的内存并没有那么多. SReclaimable: 16474128 kB (这些是内核保持的但是可以释放的inode和dentry的缓存).

下载工具 Aria2 (几乎全能的下载神器) - 简书

- -
说完了前面一堆BT/PT客户端,现在终于轮到Aria2了,关于这个我就不介绍太多了,自从百度限速以来我觉得这个快变成众所周知的了,我平时也收集了各种和Aria2相关的插件或者是辅助软件之类的,就等着全部丢出来,下面请看我的表演. 安装Aria2确实是个麻烦事,特别是要安装新的版本,我之前也写过编译安装最新版本的,看的人挺多的,就是还是麻烦了点,这次顺便给出个别人静态编译的地址,作者更新的挺勤的,基本上新版本出了很快就会跟进.

脸最黑的星球,几乎吸收了百分之百的光线

- ArmadilloCommander - 煎蛋
开普勒望远镜近日发现了宇宙中最黑的一颗行星. 这颗名叫TrES-2b的行星有木星大小,在七百五十光年开外的地方. 它比煤炭或者说黑色丙烯颜料还要黑. 不过这颗行星也不是完全黑暗的,它发出了微弱的红光,如同是正在燃烧的灰烬. TrES-2b的脸如此黑的原因,在于它离它的恒星太近了,只相当于地球到太阳的三十分之一.

北京现山寨取款机套取账户密码 几乎乱真

- Phineux - cnBeta.COM
近日,北京街头 出现一种新型骗钱手段,让人防不胜防. 不法者通过安装假的ATM机,套取持卡人的卡号和密码,进而复制银行卡窃取钱财. 宣武区广安门外西街街边一烟酒店门 口就出现了一台假ATM机. 6月15日,市民马先生在此机上插卡查询,仅得到“无法提供服务”的提示,前天他则发现卡内5000元金额不翼而飞.