第20章 最佳实践 (四)

来源:互联网 发布:潍坊网络广播电视台 编辑:程序博客网 时间:2024/05/19 13:15
 

20.4 部署

20.4.1 构建过程

你写的代码不应该原封不动地放入浏览器中,理由如下所示。

  • 知识产权问题 -- 如果把带有完整注释的代码放到线上,那别人就更容易知道你的意图,对它再利用,并且可能找到安全漏洞。
  • 文件大小 -- 书写代码要保证容易阅读,才能更好地维护,但是对于性能是不利的。浏览器并不能从额外的空白字符或者是冗长的函数名和变量名中获得什么好处。
  • 代码组织 -- 组织代码要考虑到可维护性并不一定是传送给浏览器的最好方式。
基于这些原因,最好给 JavaScript 文件定义一个构建过程。
构建过程始于在源控制中定义用于存储文件的逻辑结构。最好避免使用一个文件存放所有的 JavaScript ,遵循以下面向对象语音中的典型模式:将每个对象或自定义类型分别放入其单独的文件中。这样可以确保每个文件包含最少量的代码,使其在不引入错误的情况下更容易修改。另外,在使用像 CVS 或 Subversion 这类并发源控制系统的时候,这样做也减少了在合并操作中产生冲突的风险。
记住将代码分离成多个文件只是为了提高可维护性,并非为了部署。要进行部署的时候,需要将这些源代码合并为一个或几个归并文件。推荐 Web 应用中尽可能使用最少的 JavaScript 文件,是因为 HTTP 请求是 Web 中的主要性能瓶颈之一。记住通过 <script> 标记引用 JavaScript 文件是一个阻塞操作,当代码下载并运行的时候会停止其他所有的下载。因此,尽量从逻辑上将 JavaScript 代码分组成部署文件。 
一旦组织好文件和目录结构,并确定哪些要出现在部署文件中,就可以创建构建系统了。Ant 构建工具 (http://ant.apache.org) 是为了自动化 Java 构建过程而诞生的,不过因为其应用性和应用广泛,而在 Web 应用开发人员中也颇流行,诸如 Julien Lecomte 的软件工程师,已经写了教程指导如何使用 Ant 进行 JavaScript 和 CSS 的构建自动化。
Ant 由于其简便的文件处理能力而非常适合 JavaScript 编译系统。例如,可以很方便地获得目录中的所有文件的列表,然后将其合并为一个文件,如下所示:
该 build.xml 文件定义了两个属性:输出最终文件的构建目录,以及 JavaScript 源文件所在的源目录。目标 js.concatenate 使用了 <concat> 元素来指定需要进行合并的文件的列表以及结果文件所要输出的位置。<filelist> 元素用于指定 a.js 和 b.js 要首先出现在合并的文件中,<fileset> 元素指定了之后要添加到目录中的其他所有文件,a.js 和 b.js 除外。结果文件最后输出到 /js/output.js 。
如果安装了 Ant ,就可以进入 build.xml 文件所在的目录,并运行以下命令:
ant 
然后构建过程就开始了,最后生成合并了的文件。如果在文件中还有其他目标,可以使用以下代码仅执行 js.concatenate 目标:
ant js.concatenate
可以根据需求,修改构建过程以包含其他步骤。在开发周期中引入构建这一步能让你在部署之前对 JavaScript 文件进行更多的处理。

20.4.2 验证

尽管现在出现了一些可以理解并支持 JavaScript 的 IDE,大多数开发人员还是要在浏览器中运行代码以检查其语法。这种方法有一些问题。首先,验证过程难以自动化或者在不同系统间直接移植。第二,除了语法错误外,很多问题只有在执行代码的时候才会遇到,这给错误留下了空间;有些工具可以帮助确定 JavaScript 代码中潜在的问题,其中最著名的就是 Douglas Crockford 的 JSLint (www.jslint.com)。
JSLint 可以查找 JavaScript 代码中的语法错误以及常见的编码错误。它可以发掘的一些潜在问题如下所示:
  • eval() 的使用;
  • 未声明变量的使用;
  • 遗漏的分号;
  • 不恰当的换行;
  • 错误的逗号使用;
  • 语句周围遗漏的括号;
  • switch 分支语句中遗漏的 break;
  • 重复声明的变量;
  • with 的使用;
  • 错误使用的等号 (替代了双等号或三等号);
  • 无法到达的代码。
为了方便访问,它有一个在线版本,不过它也可以使用基于 Java 的 Rhino JavaScript 引擎 (www.mozilla.org/rhino/) 运行于命令行模式下。要在命令行中运行 JSLint ,首先要下载 Rhino,并从 www.jslint.com/ 下载 Rhino 版本的 JSLint 。一旦安装完成,便可以使用下面的语法从命令行运行 JSLint 了:
java -jar rhino-1.6R7.jar jslint.js [输入文件]
如这个例子:
java -jar rhino-1.6R7.jar jslint.js a.js b.js c.js
如果给定文件中有任何语法问题或者是潜在的错误,则会输出有关错误和警告的报告。如果没有问题,代码会直接结束而不显示任何信息。
可以使用 Ant 将 JSLint 作为构建过程的一部分运行,添加如下一个目标:
这个目标假设 Rhino.jar 文件的位置已经由叫做 rhino.jar 的属性指定了,同时 JSLint Rhino 文件的位置由叫做 jslint.js 的属性指定了。Output.js 文件被传递给 JSLint 进行校验,然后显示找到的任何问题。
给开发周期添加代码验证这个环节有助于避免将来可能出现的一些错误。建议开发人员给构建过程加入某种类型的代码验证作为确定潜在问题的一个方法,防患于未然。

20.4.3 压缩

当谈及 JavaScript 文件压缩,其实在讨论两个东西:代码长度和配重 (Wire weight) 。代码长度指的是浏览器所需解析的字节数,配重指的是实际从服务器传送到浏览器的字节数。在 Web 开发的早期,这两个数字几乎是一样的,因为从服务器端到客户端原封不动地传递了源文件。而在今天的 Web 上,这两者很少相等,实际上也不应相等。
1.文件压缩
因为 JavaScript 并非编译为字节码,而是按照源代码传送的,代码文件通常包含浏览器执行所不需要的额外的信息和格式。注释,额外的空白,以及长长的变量名和函数名虽然提高了可读性,但却是传送给浏览器时不必要的字节。不过,我们可以使用压缩工具减少文件的大小。
压缩器一般进行如下一些步骤:
  • 删除额外的空白 (包括换行);
  • 删除所有注释;
  • 缩短变量名。
JavaScript 有不少压缩工具可用,其中最优秀的是 YUI 压缩器,http://devloper.yahoo.com/yui/compressor/ 。YUI 压缩器使用了 Rhino JavaScript 解析器将JavaScript 代码令牌化。然后使用这个令牌流创建代码不包含空白和注释的优化版本。与一般的基于表达式的压缩器不同的地方在于,YUI 压缩可以确保不引入任何语法错误,并可以安全地缩短局部变量名。
YUI 压缩器是作为 Java 的一个 jar 文件发布的,名字叫 yuicompressor-x.y.z.jar ,其中 x.y.z 是版本号。可以使用以下命令行格式来使用 YUI 压缩器:
java -jar yuicompressor-x.y.z.jar [选项] [输入文件]
YUI 压缩器的选项列在了下面的表格内。
例如,以下命令可以用来将 CookieUtil.js 压缩成一个叫做 cookie.js 的文件:
java -jar yuicompressor-2.3.5.jar -o cookie.js CookieUtil.js
YUI 压缩器也可以通过直接调用 java 可执行文件在 Ant 中使用,如下面的例子所示:
该目标包含了一个文件 output.js ,由构建过程生成的,并传递给 YUI 压缩器。输出文件指定为同一目录下的 output-min.js 。这里假设 yuicompressor.jar 属性包含了 YUI 压缩器的 jar 文件的位置。然后可以使用以下命令运行这个目标:
ant js.compress
所有的 JavaScript 文件在部署到生成环境之前,都应该使用 YUI 压缩器或者类似的工具进行压缩。给构建过程添加一个压缩 JavaScript 文件的环节以确保每次都进行这个操作。
2.HTTP 压缩
配重指的是实际从服务器传送到浏览器的字节数。因为现在的服务器和浏览器都有压缩功能,这个字节数不一定和代码长度一样。所有的五大 web 浏览器 (IE、Firefox、Safari、Chrome 和 Opera) 都支持对所接收的资源进行客户端解压缩。这样服务器端就可以使用服务器端相关功能来压缩 JavaScript 文件。一个指定了文件使用了给定格式进行了压缩的 HTTP 头包含在了服务器响应中。接着浏览器会查看该 HTTP 头确定文件是否已被压缩,然后使用合适的格式进行解压缩。结果是和原来的代码量相比在网络中传递的字节数量大大减少了。
对于 Apache web 服务器,有两个模块可以进行 HTTP 压缩:mod_gzip (Apache1.3.x) 和 mod_deflate (Apache 2.0.x) 。对于 mod_gzip ,可以给 httpd.conf 文件或者是 .htaccess 文件添加以下代码启用对 JavaScript 的自动压缩:
#告诉 mod_gzip 要包含任何以 .js 结尾的文件
mod_gzip_item_include file \.js$
该行代码告诉 mod_gzip 要包含来自浏览器请求的任何以 .js 结尾的文件。假设你所有的 JavaScript 文件都以 .js 结尾,就可以压缩所有请求并应用何时的 HTTP 头以表示内容已被压缩。关于 mod_zip 的更多信息,请访问项目网站 http://www.sourceforge.net/projects/mod-gzip/ 。
原创粉丝点击