应用程序似乎都有一个内部版本号,不是吗?无论您在何处寻求有关管理大型软件项目的建议,您都会发现自动化构建过程实际上是一项要求。我发现自动化构建过程至关重要,该过程可以连接并缩小给定页面所需的文件。本教程将揭开 Ant 构建工具的神秘面纱,并向您展示如何为 JavaScript 库创建您自己的、灵活的构建文件。
对于本教程,您将需要安装了 Ant 的 NetBeans。我经常使用:
PHP 版本中的 Ant 工具是一个稍微受限的版本,但对于我们的目的来说是理想的,因为 PHP 项目并不复杂,自动生成的构建文件。因此,在本教程中,我将使用 PHP 版本进行演示。然而,Ant 当然可以在 Apache 上使用,并且广泛用于 IDE,例如 Eclipse。对于 .Net C# 社区,有一个名为 Nant 的工具,我在 .NET 项目中使用它 - 它非常相似。
在我第一次认真尝试创建单页 Ajax 应用程序时,我最终得到了一个包含近 40 个脚本标记的列表,这些脚本标记的启动时间超过一分钟。为了使项目易于管理,我需要将代码包含在多个模块中,更不用说所需的所有 YUI 模块了。在阅读了 YUI 团队写的博客后,我意识到将脚本标签的数量减少到尽可能少的数量对于性能来说是多么重要。因此,我对连接和缩小 JavaScript 文件感兴趣。
组合多个文件可以减少 HTTP 标头中的额外字节以及 TCP 慢启动、数据包丢失等导致的潜在传输延迟。
YUI 博客:性能研究,第 6 部分
Lajos Moczar 出色的 Tomcat 5 Unleashed 对我开发完整的基于 Web 应用程序的态度产生了巨大影响。它不仅仅是一本关于 Tomcat 的书。它给了我开始使用 Ant 构建 JSP 项目的动力、指导和勇气。 Ant 内置于 NetBeans 中,NetBeans 是我最喜欢的 JSP IDE,我习惯于使用自动生成的构建文件,在构建 Java 类包时几乎不需要手动编辑。然而,随着我对 JavaScript 的理解不断加深,我发现我需要一个构建过程,并且被迫为项目的 JavaScript 部分手动编写自己的构建配置文件。 Moczar 的 Tomcat 应用程序的 build.xml 给了我一个很好的起点。
拥有良好的开发环境对于开发工作的成功绝对关键。您需要一个结构化环境,允许您以高效且可重复的方式执行构建流程。
- Lajos Moczar,《雄猫 5 释放》
编者注:如果您决定不使用 Ant,Grunt 是您的 JavaScript 应用程序的绝佳构建工具。在 Nettuts+ 上了解更多相关信息。
在 NetBeans 中打开一个新项目。我将我的 NetTutsBuildJs 命名为 NetTutsBuildJs,并在我的 Nettuts+ 文件夹中创建了它:C:NetTutsBuildJs
。显然,JavaScript 不需要编译成 exe
文件;我们有不同的担忧。对于一个大型 JavaScript 项目,我们至少需要三样东西:
正如您在屏幕截图中看到的,我为 JavaScript 创建了一个名为 js
的文件夹,然后添加了文件夹 src
、concat
和 min
。
我对在每个新的 IT 教程开始时说“Hello World”感到有点厌倦,不是吗?所以我想这次忽略这个世界会很好。毕竟,这可能只是我的想象!
我是一个唯我论者。为什么我们没有更多的人?
build.xml
的新 XML 文档。
<project name="NetTutBuildJs" basedir="."> </project>
您现在可能没有注意到任何事情,但是如果您重新启动 IDE,您将看到 build.xml
现在有一个特殊的图标,其中带有与 Ant 文件关联的黄色三角形。如果选择它,您将看到导航器面板现在在其标题中显示 Ant Targets。
Ant 构建文件中的每组任务称为一个目标,因此我们需要创建一个简单的消息目标
嵌套在项目标签内,如下所示:
<target name="ignore-world-message"> <echo message="World. You may be a figment of my imagination."></echo> </target>
现在,在“项目”面板中展开 build.xml
文件,您将在“导航器”面板中看到新目标。右键单击“ignore-world-message”,您应该会在“输出”面板中看到该消息,如下所示:
正确的。这个世界可能并不存在,我们也忽略了它,但至少 Ant 似乎在工作!开个玩笑,我们现在必须正确处理 Ant 中最关键的事情:路径。
我可能有点慢,但我总是遇到麻烦,所以让我们小心行事。将属性添加到文件顶部、项目标记下方。调用属性root并将位置设置为零长度字符串。
<property name="root" location="" />
添加一个新目标来显示此位置,以便我们可以确保我们的路径是笔直的。注意到引用根属性的复杂语法了吗?您需要将属性名称括在双引号内,但此外,您还必须用美元符号和左侧的大括号将其括起来,然后用右侧的大括号将其封闭。真是大惊小怪!
<target name="show-root-path"> <echo message="${root}"/> </target>
您可以将其放在忽略世界目标之后。现在,当您右键单击 show-root-path
目标以显示上下文菜单,然后单击“运行目标”时,您应该会看到项目根目录的正确路径。就我而言:C:NetTutsBuildJs
。
迷人的。我们已经有了环境,并且有了指向硬盘驱动器上正确位置的根路径。现在我们可以添加其他路径。
<property name="js" location="${root}/js" /> <property name="src" location="${js}/src" /> <property name="concat" location="${js}/concat" /> <property name="min" location="${js}/min" />
最后,一些真正的工作。我们添加一个新目标,其中包含 concat
标记,如下所示:
<target name="concat"> <concat destfile="${concat}/tree-concat.js" encoding="UTF-8" > <filelist dir="${src}" files= "tree_data.js, tree.js" > </filelist> </concat> </target>
这只是一个简单的示例,但为了快速进行操作,我创建了两个简单的 JavaScript 文件: tree_data.js
和 tree.js
,它们依赖于 YUI 文件 yahoo-dom -event.js
和 treeview-min.js
。 tree_data.js
有以下毫无意义的内容:
var treeData = [{ "label": "Britain", "children":[ "London", "Edinburgh" ] },{ "label": "France", "children":[ "Paris", "Lyon" ] },{ "label": "Japan", "children":[ "Tokyo", "Kyoto" ] },{ "label": "Thailand", "children":[ "Bangkok", "Pattaya" ] }]
tree.js
只是用该数据渲染 TreeView
。
YAHOO.util.Event.onDOMReady(function(){ var tree = new YAHOO.widget.TreeView("tree", treeData); tree.render(); });
请注意,文件列表标签正是我们在这里所需要的。在 JavaScript 中,顺序很重要,因此我们可能首先需要数据,然后是渲染文件。如果我们使用依赖于操作系统中文件的自然顺序的标签,我们可能会以错误的顺序获取它们。因此,我们费力地在 filelist
标记中手动输入列表,以确保我们想要的顺序。
对于 JavaScript 纯粹主义者来说:我知道我的
treeData
变量是一个全局变量,我应该以不同的方式来做。这只是一个解释如何使用 Ant 的简单示例。我确信学习本教程的人也在遵循其 JavaScript 库的当前最佳实践。
现在运行 concat
目标。你瞧,在 concat
目录下神奇地出现了一个名为 tree-concat.js
的文件,打开它,可以看到顶部定义的数据和底部的渲染函数。 p>
为了尝试这个,我创建了两个简单的 html 文件:tree_src.html
和 tree_concat.html
。在标头中,它们都具有指向为 TreeView 创建 Sam 皮肤所需的 CSS 文件的相同链接。
<link rel="stylesheet" href="js/yui/fonts-min.css"> <link rel="stylesheet" href="js/yui/treeview.css"> <link rel="stylesheet" href="js/yui/treeview-skin.css">
在 tree_src.html
正文末尾之前,我添加了
<script src="js/yui/yahoo-dom-event.js"></script> <script src="js/yui/treeview-min.js"></script> <script src="js/src/tree_data.js"></script> <script src="js/src/tree.js"></script>
测试串联文件。我已将 tree_concat.html
中的 script
标记更改为:
<script src="js/yui/yahoo-dom-event.js"></script> <script src="js/yui/treeview-min.js"></script> <script src="js/concat/tree-concat.js"></script>
我们的树库似乎正在工作,并且当我们连接文件时,我们似乎已经得到了正确的顺序。出色的!现在终于是时候缩小所有内容并将 script
标签的数量减少到一个了。这有点复杂。
<target name="min"> <apply executable="java" parallel="false" dest="${min}" taskname="yui"> <fileset dir="${concat}"> <patternset> <include name="tree-concat.js"/> </patternset> </fileset> <arg line="-jar"></arg> <arg path="${compressor}"></arg> <arg line="--charset UTF-8"/> <arg line="-v"></arg> <srcfile/> <arg line="-o"></arg> <mapper type="glob" from="*-concat.js" to="*-min.js"></mapper> <targetfile/> </apply> </target>
注意属性压缩器。为了让这一切运行,我将 YUI 压缩器 jar 文件复制到项目中的 yui_compressor
文件夹,并在构建文件中创建一个属性:
<property name="compressor" location="${root}/yui_compressor/yuicompressor-2.4.2.jar"/>
当我们运行 min
目标时,您现在应该会看到此输出以及 min
文件夹中名为 tree-min.js
的新文件。如果打开它,您将看到一长串连续的 JavaScript,没有空格,全部在一行中。
还需要一个目标:将两个 YUI 文件与我们新的缩小文件连接起来。
<target name="all"> <concat destfile="${min}/all-tree-min.js" encoding="UTF-8" > <filelist dir="${yui}" files= "yahoo-dom-event.js, treeview-min.js" > </filelist> <filelist dir="${min}" files= "tree-min.js" > </filelist> </concat> </target>
在测试文件tree_min.html
中,我现在只需要一个script
标签:
<script src="js/min/tree-min.js"></script>
最后一步是添加一个目标,该目标调用所有必要的目标并以正确的顺序运行它们。惯例是将此目标称为构建。使用 clean 目标来删除 concat
和 min
目录以及使用 init 目标来设置这些目录也很有用。
<target name="clean"> <delete dir="${concat}"/> <delete dir="${min}"/> </target> <target name="init"> <mkdir dir="${concat}"/> <mkdir dir="${min}"/> </target>
构建目标现在应该运行:
组合所有这些的方法就是简单地将它们添加到 dependent 属性中,如下所示。
<target name="build" depends="clean, init, concat, min, all"> </target>
我们演练了为 Ant 创建配置文件以构建 JavaScript 库所需的步骤。
在本教程中,我们演练了为 Ant 创建配置文件以构建 JavaScript 库所需的步骤。从源代码开始,我们将库中的所有文件连接成一个文件,确保每个源文件都按正确的顺序添加。我们测试了生成的串联文件,以确保没有任何内容丢失或错位。然后我们缩小了该文件并将其与其依赖的 YUI 文件连接起来。
最终结果是我们的网页只有一个 script
标签,其中包含运行该页面所需的所有复杂 JavaScript。我想您可以看到将这个示例应用到一个非常大的复杂 JavaScript 库是多么容易。以这个基本示例为起点,您应该能够探索 Ant 文档并开发一个完整工作的构建文件,以自动化构建过程的每个部分。
我还使用 Ant for SQL 构建数据库的本地克隆。
此外,我也对 CSS 文件使用这种构建。它们几乎可以变得和 JavaScript 文件一样复杂,连接和缩小它们确实很有帮助。我还使用 Ant for SQL 构建数据库的本地克隆。我发现,当我想重新开始一个项目、清理所有实验代码并从头开始时,带一个漂亮的全新数据库确实很有用。 Ant 工具可以轻松快速构建表、函数和过程,然后用一些示例数据填充该内容。