前言

如果你想开发一个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地址,作者等等,比如:

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

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

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

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

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

1
2
3
4
5
6
7
8
9
...
<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,写上我们自己的单元测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 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'));
}
});
});
...

然后在命令行运行一下grunt qunit 运行结果是这样的:

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

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

最终的功能js如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 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));

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

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

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

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

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

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

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

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

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

第四招:利用 watch 自动化

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

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

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

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

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

小结

本文的示例代码已经放到 github 上

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

参考

grunt init

利用 Grunt (几乎)无痛地做前端开发 (一)之单元测试的更多相关文章

  1. 用grunt搭建自动化的web前端开发环境实战教程(详细步骤)

    用grunt搭建自动化的web前端开发环境实战教程(详细步骤) jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用!前端自动化, ...

  2. 【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过 ...

  3. 转:【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    原文地址:http://blog.csdn.net/wangfupeng1988/article/details/46418203 jQuery在使用grunt,bootstrap在使用grunt,百 ...

  4. 用grunt搭建自动化的web前端开发环境-完整教程

    原稿:http://www.cnblogs.com/wangfupeng1988/p/4561993.html#!comments jQuery在使用grunt,bootstrap在使用grunt,百 ...

  5. 用grunt搭建自动化的web前端开发环境

    用grunt搭建自动化的web前端开发环境 jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发 ...

  6. grunt搭建自动化的web前端开发环境(转)

    1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过.但是不会熟练使用grunt,那你就真的真的真的out了(三个“真的”重复,表示重点).至于grunt的作用,这里不详细说了, ...

  7. 使用grunt搭建自动化的web前端开发环境

    使用grunt搭建自动化的web前端开发环境 我们一定经常听过grunt和gulp,它们都是用于搭建自动化的web前端开发环境的,这里主要介绍grunt的使用,值得一提的是,jQuery.bootst ...

  8. 从cocos2d-html5中提取出来的,用做前端开发的框架——cc.js

    从cocos2d-html5中提取出来的,用做前端开发的框架——cc.js /************************************************************* ...

  9. 简单利用jQuery加tomcat,让前端开发不再依赖于后端的接口

    前端开发的过程中,我们免不了和后端进行联调,这时候就会出现以下的尴尬场景: 接口没写好,没法做接下来的功能 功能写好了,接口没写好,没法测这个功能 联调了,除了BUG,不知道锅在谁身上,只得陪后端耗时 ...

随机推荐

  1. JavaBean-- 保存 范围

    1. page:当前页 2. request:一次服务器跳转范围中 3. session:一次用户操作范围,重新打开浏览器失效 4. application:整个服务器保存,服务器关闭才失效 定义一个 ...

  2. Ubuntu Linux系统下apt-get命令详解

    整理了Ubuntu Linux操作系统下apt-get命令的详细说明,分享给大家.常用的APT命令参数: apt-cache search package 搜索包 apt-cache show pac ...

  3. HDU 5170 GTY's math problem

    数学题,a的b次方和c的d次方都很大,直接判断是做不出来的. 如果我们能找到一个函数F(x)是单调的,而F(X)的值又比较好算,那么可以通过比较F(X)的大小来判断自变量的大小. 令F(X)=log( ...

  4. 关于Bean\Entity\Model\POJO的一些个人理解

    本文没有长篇累牍的,严格的,标准的表述,只是我在开发过程中,读书过程中的一些个人理解,可能不太准备,但是我觉得应该是最方便初学者理解的吧? 一.Bean 对于Bean而言,我的理解是只要是Java的类 ...

  5. HDU 5176 The Experience of Love 带权并查集

    The Experience of Love Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/O ...

  6. Python之路:线程池

    版本一 #!/usr/bin/env  python # --*--coding:utf-8 --*-- import Queue import threading class ThreadPool( ...

  7. 定时且周期性的任务研究I--Timer

    很多时候我们希望任务可以定时的周期性的执行,在最初的JAVA工具类库中,通过Timer可以实现定时的周期性的需求,但是有一定的缺陷,例如:Timer是基于绝对时间的而非支持相对时间,因此Timer对系 ...

  8. C#设置word段落首行缩进为0

    PublicVar.m_WordApp.Selection.ParagraphFormat.CharacterUnitFirstLineIndent = ; PublicVar.m_WordApp.S ...

  9. Android学习笔记之Intent(2)

    打开网页 package com.jiahemeikang.helloandroid; import java.io.File; import com.jiahemikang.service.Echo ...

  10. ASP.NET AJAX注册命名空间

    AJAX库支持命名空间的概念. 类可以分组到不同的命名空间.AJAX库会自动创建在此层次中不存在的任何级别的命名空间. <%@ Page Language="C#" Auto ...