项目build实战—ant入门指南(9)
前面8篇ant教程,基本上没有太复杂的地方,在实际项目build中会遇到些复杂的场景。今天这篇教程,明河将通过一个真实的项目build过程,来综合演练下ant的用法,同时演示下如何处理ant中的循环任务。
项目简介
项目名:KF(KISSY-FORM)
用途:kissy的form组件包
源码地址:https://github.com/minghe/kissy-form
KF目前还在开发阶段,完成的组件只有Uploader(异步文件上传),日后会发布更多的form组件,有兴趣的朋友可以关注下。
Uploader场景足够复杂,足以覆盖ant的大部分常用用法,请先下载KF源码到本地,找到Uploader的build.xml文件(form/src/uploader/build.xml)。
build目标
build(构建后的打包发布文件)必须和src(源码目录)目录结构保持一致。
- 合并src下的所有js为render-pkg.js(排除themes、demo、auth、tests目录下的文件)
- 将render-pkg.js移动到build目录下,并改名为render.js
- copy一份themes目录到build/form/uploader
- 遍历themes下的每个目录,将子目录下的所有js合并成index-pkg.js
- 删除除了index-pkg.js外的所有js文件
- 将index-pkg.js改名为index.js
- 压缩build目录下的所有js文件
- copy一份uploader.swf文件到build目录下
任务是不是很多,也许你会觉得明河搞得这么复杂很蛋疼,实际上这些任务跟明河实际要实现的构建目标有关,不是本文重点,这里不讨论。
接下来来看明河是如何实现这些目标的。
由于需要用到第三方类库ant-contrib-1.0b3.jar,请先下载该文件到你的ant/lib目录下。
点此下载
ant实战
合并src下的所有js为render-pkg.js(排除themes、demo、auth、tests目录下的文件)
<target name="concat">
<concat destfile="render-pkg.js" encoding="${charset}" outputencoding="${charset}">
<fileset dir="${src.dir}" includes="**/*.js" excludes="tests/*.js,demo/**/*.js,auth/*.js,themes/**/*.js"/>
<filterchain>
<deletecharacters chars=""/>
</filterchain>
</concat>
</target>
关于concat的用法可以看《认识基础任务标签(上)—ant入门指南(3)》。
<target name="concat">
<concat destfile="render-pkg.js" encoding="${charset}" outputencoding="${charset}">
<fileset dir="${src.dir}" includes="**/*.js" excludes="tests/*.js,demo/**/*.js,auth/*.js,themes/**/*.js"/>
<filterchain>
<deletecharacters chars=""/>
</filterchain>
</concat>
</target>
将render-pkg.js移动到build目录下,并改名为render.js
<target name="move"><br />
<move file="render-pkg.js" tofile="${uploader.build.dir}/render.js"/>
</target>
改名操作不一定要用rename标签,使用move标签也可以间接实现。
copy一份themes目录到build/form/uploader,并删除目录下的html文件
<target name="move-theme">
<copy todir="${uploader.build.dir}/themes" overwrite="true">
<fileset dir="${src.dir}/themes"/>
</copy>
<delete>
<fileset dir="${uploader.build.dir}/themes" includes="**/*.html"/>
</delete>
</target>
这部分的目标也非常简单,使用copy和delete即可实现。
遍历themes下的每个目录,将子目录下的所有js合并成index-pkg.js。删除除了index-pkg.js外的所有js文件。>将index-pkg.js改名为index.js
好,进入本文的重点内容,这个任务目标有个难点,就是如何在ant中处理循环?
如上图所示,build和src下的themes目录必须保持一致,而且必须遍历每个子目录合并该目录的js,所以需要用到循环。这时候你也许会想到编程语言中常用的for,ant有for标签吗?很影响ant并不是编程语言,没有直接的for标签,但通过第三方类库可以实现for循环,我们来看代码。
请确保你的本机上的ant下的lib目录下有ant-contrib-1.0b3.jar文件。
增加新的命名空间
<project name="uploader.build" default="build" basedir="." xmlns:ac="antlib:net.sf.antcontrib">
</project>
给你的project增加ac命名空间: mlns:ac=”antlib:net.sf.antcontrib” 。
遍历themes下的每个目录
<target name="build-theme" depends="move-theme">
<ac:for param="file">
<path>
<fileset dir="${uploader.build.dir}/themes" includes="**/index.js"/>
</path>
<sequential>
<ac:var name="var.dir" unset="true"/>
<dirname property="var.dir" file="@{file}"/>
<echo>concat ${var.dir}</echo>
</sequential>
</ac:for>
</target>
使用ac:for开启循环,param为参数名,供后面循环时更换文件路径时使用。
<path>
<fileset dir="${uploader.build.dir}/themes" includes="**/index.js"/>
</path>
定义文件路径。取每个子目录下的index.js。
<sequential>
<ac:var name="var.dir" unset="true"/>
<dirname property="var.dir" file="@{file}"/>
<echo>concat ${var.dir}</echo>
</sequential>
sequential 标签,与for标签配合使用,标志循环开始。
ac:var 定义var.dir变量(即子目录路径)可更改,留意ant定义的property是无法更改的。
dirname 获取文件对应的子目录路径。
接下来具体执行任务:
<concat destfile="${var.dir}/index-pkg.js" encoding="${charset}" outputencoding="${charset}">
<fileset dir="${var.dir}" includes="*.js"/>
<filterchain>
<deletecharacters chars=""/>
</filterchain>
</concat>
<delete>
<fileset dir="${var.dir}/" includes="*.js" excludes="index-pkg.js"/>
</delete>
<rename src="${var.dir}/index-pkg.js" dest="${var.dir}/index.js"/>
压缩build目录下的所有js文件
<target name="minify" depends="crlf">
<apply executable="java" verbose="true" dest="${uploader.build.dir}" failοnerrοr="true" parallel="false">
<fileset dir="${uploader.build.dir}" includes="**/*.js"/>
<arg line="-jar"/>
<arg path="${compiler}"/>
<arg line="--charset utf8"/>
<arg value="--warning_level"/>
<arg value="QUIET"/>
<arg value="--js"/>
<srcfile/>
<arg value="--js_output_file"/>
<targetfile/>
<mapper type="regexp" from="^(.*)\.js$" to="\1-min.js"/>
</apply>
</target>
关于如何使用ant压缩脚本可以看《ant结合yui-compressor和closure-compiler—ant入门指南》。
其他简单的部分不再累述。
完整代码如下:
<project name="uploader.build" default="build" basedir="." xmlns:ac="antlib:net.sf.antcontrib">
<description>Uploader Build File</description>
<property name="charset" value="utf-8"/>
<property name="tool.dir" location="../../../tool"/>
<property name="compiler" location="${tool.dir}/closure-compiler/compiler.jar"/>
<property name="form.build.dir" location="../../../build/form"/>
<property name="src.dir" location="."/>
<property name="uploader.build.dir" location="${form.build.dir}/uploader"/>
<!--合并源码文件,排除模板js-->
<target name="concat">
<concat destfile="render-pkg.js" encoding="${charset}" outputencoding="${charset}">
<fileset dir="${src.dir}" includes="**/*.js" excludes="tests/*.js,demo/**/*.js,auth/*.js,themes/**/*.js"/>
<filterchain>
<deletecharacters chars=""/>
</filterchain>
</concat>
</target>
<!--移动合并后源文件到build目录下-->
<target name="move">
<move file="render-pkg.js" tofile="${uploader.build.dir}/render.js"/>
</target>
<!--删除build目录下的所有文件-->
<target name="clean-build">
<delete>
<fileset dir="${uploader.build.dir}" includes="**/*.js,**/*.css,**/*.swf"/>
</delete>
</target>
<!--移动uploader.swf-->
<target name="move-swf">
<copy file="plugins/ajbridge/uploader.swf" todir="${uploader.build.dir}/plugins/ajbridge"/>
</target>
<!--移动模板的源码文件到build目录下-->
<target name="move-theme">
<copy todir="${uploader.build.dir}/themes" overwrite="true">
<fileset dir="${src.dir}/themes"/>
</copy>
<delete>
<fileset dir="${uploader.build.dir}/themes" includes="**/*.html"/>
</delete>
</target>
<!--构建模板,合并模板下的js文件,生成index-pkg.js,删除源文件,将index-pkg.js改成index.js-->
<target name="build-theme" depends="move-theme">
<ac:for param="file">
<path>
<fileset dir="${uploader.build.dir}/themes" includes="**/index.js"/>
</path>
<sequential>
<ac:var name="var.dir" unset="true"/>
<dirname property="var.dir" file="@{file}"/>
<echo>concat ${var.dir}</echo>
<concat destfile="${var.dir}/index-pkg.js" encoding="${charset}" outputencoding="${charset}">
<fileset dir="${var.dir}" includes="*.js"/>
<filterchain>
<deletecharacters chars=""/>
</filterchain>
</concat>
<delete>
<fileset dir="${var.dir}/" includes="*.js" excludes="index-pkg.js"/>
</delete>
<rename src="${var.dir}/index-pkg.js" dest="${var.dir}/index.js"/>
</sequential>
</ac:for>
</target>
<!--压缩前去除页面多余空白-->
<target name="crlf">
<fixcrlf includes="*.js" srcdir="${uploader.build.dir}" encoding="utf8" eol="crlf"></fixcrlf>
</target>
<!--压缩脚本-->
<target name="minify" depends="crlf">
<apply executable="java" verbose="true" dest="${uploader.build.dir}" failοnerrοr="true" parallel="false">
<fileset dir="${uploader.build.dir}" includes="**/*.js"/>
<arg line="-jar"/>
<arg path="${compiler}"/>
<arg line="--charset utf8"/>
<arg value="--warning_level"/>
<arg value="QUIET"/>
<arg value="--js"/>
<srcfile/>
<arg value="--js_output_file"/>
<targetfile/>
<mapper type="regexp" from="^(.*)\.js$" to="\1-min.js"/>
</apply>
</target>
<target name="build" depends="concat,clean-build,move,build-theme,minify,move-swf">
</target>
</project>
转自:http://www.36ria.com/5003