`
Cjch
  • 浏览: 111451 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

试用Google Closure Compiler的API

阅读更多
(转)
原来的JS压缩服务采用的是YUI Compressor,一年下来表现还算稳定。

今天老高说想尝试一下Google Closure Compiler,翻了翻文档,看看有没API能直接用的:传一个原始字符串,返回一个压缩后的字符串。找了半天,没有此类的例子(看来设计者认为像我们这样直接采用API而不是使用命令行的用户不多)。

查看JavaDoc,定位到com.google.javascript.jscomp.Compiler,有如下描述:
Compiler (and the other classes in this package) does the following:
* parses JS code
* checks for undefined variables
* performs optimizations such as constant folding and constants inlining
* renames variables (to short names)
* outputs compact javascript code
看来就是这个了。

相中方法: Result compile(JSSourceFile extern, JSSourceFile input, CompilerOptions options) 。
input和options容易理解,extern是什么?其实类的描述里也稍微提了下:
External variables are declared in ‘externs’ files. For instance, the file may include definitions for global javascript/browser objects such as window, document.
很显然可以没有extern(但不能为NULL,设置方法参看底下的代码)。

按道理,编译后返回的result里应该就有我想要的结果了吧,结果出乎意料。Result只有编译状态的描述。难道此路不通?

又从JAR包的 META-INF看到入口类是CompilerRunner,一路追踪下去。。。中间省略文字几千字。绕了半天,得出的结论是:和 CompilerRunner相关的几个类很难复用,想用的方法要么是不可见,要么是包可见,要么是子类可见。代理来继承去,眼看就OK了,又发现很多状态居然是static的,这使得程序的状态是迭加的。看来此路也不通。。。又绕回Compiler。晕,原来Compiler有一个方法 toSource()就是返回压缩化的代码的。

这下好办了。主要代码如下:
final ByteArrayOutputStream err = new ByteArrayOutputStream();
final PrintStream errWrapper = new PrintStream(err);
final Compiler compiler = new Compiler(errWrapper);

final ByteArrayInputStream bais = new ByteArrayInputStream(codeBytes);

final CompilerOptions options = new CompilerOptions();
final CompilationLevel level = CompilationLevel.SIMPLE_OPTIMIZATIONS
level.setOptionsForCompilationLevel(options);

final Result status = compiler.compile(JSSourceFile.fromCode("extern", ""), JSSourceFile.fromInputStream("input", bais), options);
System.out.println(compiler.toSource);

把代码布上后,测试通过。本来这是一件小事,没必要以此作为BLOG的内容。但是这件事也是给了我几个感触,觉得有必要说一说:
一、文档很重要。简单的几句话,也许就能让用户少走很多弯路。DAL后面一定要多写文档,特别是使用手册。
二、API设计要符合直觉。不符合直觉的设计会造成大量的困扰。当年Lucene的delete操作,用脚跟想想就应该放在IndexWriter里,可设计者却把它放在IndexReader里,结果邮件列表里经常出现此类的问题。当然,后续版本已经做了修改(IndexWriter有了delete方法)。用户不会关心你为什么这么做;新用户要抛弃你只要点一下鼠标就可以了;而老用户选择离开只需要皱一下眉头。
三、时间管理很重要。任何事情都应该在任务框架里进行;否则,很多东西可能会失控。

—The end.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics