在 Ant 的构建过程描述文件(build.xml)中,可以参考如下例子来引入。
<property name="dir.lib.yuicompress" value="lib"/><!-- 存放 YUI Compress 二个 .jar 文件的目录 --> <property name="dir.build.js" value="dist/webapp/js"/><!-- 存放压缩过的 JavaScript 文件目录 --> <property name="dir.build.css" value="dist/webapp/css"/><!-- 存放压缩过的 CSS 文件目录 --> <property name="dir.src.js" value="web/js"/><!-- JavaScript 源文件目录 --> <property name="dir.src.css" value="web/css"/><!-- CSS 源文件目录 --> <path id="path.build.classpath.yuicompress"> <fileset dir="${dir.lib.yuicompress}"> <include name="yuicompressor-2.4.2.jar"/> <include name="YUIAnt.jar"/> </fileset> </path> <target name="compres-js-css" description="压缩 .js 和 .css 文件"> <taskdef name="compress" classname="com.yahoo.platform.yui.compressor.YUICompressTask"> <classpath refid="path.build.classpath.yuicompress"/> </taskdef> <compress linebreak="150" warn="false" munge="yes" preserveallsemicolons="true" outputfolder="${dir.build.js}"> <fileset dir="${dir.src.js}"> <include name="**/*.js"/> </fileset> </compress> <compress linebreak="150" warn="false" munge="yes" charset="UTF-8" preserveallsemicolons="true" outputfolder="${dir.build.css}"> <fileset dir="${dir.src.css}"> <include name="**/*.css"/> </fileset> </compress> </target>
其中 <compress> 标签的 charset 参数的含义是指定输出文件的字符编码集。原版存在无法以指定字符编码集读取源文件的问题。所以我对此(com.yahoo.platform.yui.compressor.YUICompressTask)进行了改造。此改造方法为原创,经测试无误。
其实,原先的设计根本就没有考虑到源文件字符编码集的问题。首先我们为 <compress> 标签增加 encoding 这个属性,用来指定源文件的字符编码集。然后在读取文件的时候,用这个 Ant 构建文件中指定的 encoding 来打开文件输入流。所有改造都只针对 com/yahoo/platform/yui/compressor/YUICompressTask.java 这一个文件。看了源文件,发现雅虎源代码的水平真是太不考究了……空格和 Tab 混用,行尾多余空白也不消除,空行也没有规范,注释也不指名调用顺序……不感叹了,下面是改写方法。
首先,要改变最开始的 import 部分。
原先的程序:
import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;改为无误:
import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream;
第二,属性确认方法要增加对 encoding 未指定的支持,并根据 YUI 官方的提议,修改 charset 默认值得逻辑。在 validate() 方法中修改。
原先的程序:
/** * */ private void validate() { if(charset==null) { charset = System.getProperty("file.encoding"); if(charset == null) { charset = "UTF-8"; } } this.munge = (this.munge != null) ? munge : Boolean.FALSE; this.lineBreak = (this.lineBreak==null) ? new Integer(-1) : this.lineBreak; }改为:
/** * Set attribute default value. * Modified by Shane Loo Li at 2012-4-4 Wednesday */ private void validate() { if (this.charset == null) { //this.charset = System.getProperty("file.encoding"); /* * Modified by Shane Loo Li at 2012-4-5 Thursday. * In YUI Compressor 2.4.7, The development team think that 'UTF-8' is better than local * charset for the output file. */ this.charset = this.charset != null ? this.charset : "UTF-8"; } if (this.encoding == null) { this.encoding = System.getProperty("file.encoding"); this.encoding = this.encoding != null ? this.encoding : "UTF-8"; } this.munge = (this.munge != null) ? munge : Boolean.FALSE; this.lineBreak = (this.lineBreak==null) ? new Integer(-1) : this.lineBreak; }其中三目运算符优先级低于比较运算,高于赋值运算,刚好不用加括号。
if(inputFile.getAbsolutePath().equals(outputFile.getAbsolutePath())) { log("Input and Output file are the same, creating a copy"); tempFile = File.createTempFile("temp", inputFile.getName().substring(inputFile.getName().lastIndexOf("."))); log("Copying "+inputFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath()); copy(inputFile, tempFile); reader = new BufferedReader(new FileReader(tempFile)); } else { reader = new BufferedReader(new FileReader(inputFile)); }改为:
if(inputFile.getAbsolutePath().equals(outputFile.getAbsolutePath())) { log("Input and Output file are the same, creating a copy"); tempFile = File.createTempFile("temp", inputFile.getName().substring(inputFile.getName().lastIndexOf("."))); log("Copying "+inputFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath()); copy(inputFile, tempFile); // Modified by Shane Loo Li a 2012-4-4 Wednesday to support different source file charset. reader = new BufferedReader(new InputStreamReader(new FileInputStream(tempFile), this.encoding)); //reader = new BufferedReader(new FileReader(tempFile)); } else { // Modified by Shane Loo Li a 2012-4-4 Wednesday to support different source file charset. reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), this.encoding)); //reader = new BufferedReader(new FileReader(tempFile)); }这么更改是因为 FileReader 不提供用指定字符编码集读取,所以要换成别的打开方式。
private String encoding;
在文件后边有一组 getter 和 setter ,增加
/** * @return the encoding */ public String getEncoding() { return this.encoding; } /** * @param set the source file encoding */ public void setEncoding(String encoding) { this.encoding = encoding; }