Closure如何调用Java API压缩Javascript文件?

2018-01-02 15:53:27 +0000

        我写此篇博文的目的是分享怎么在本地直接调用Java API来优化压缩JS代码,减少大家的摸索时间。

        在网站开发过程中,为提高访问速度常常需要对JS和CSS的文件的压缩。压缩js可以节省用户下载时间,就拿常用的jquery-3.3.1.js和jquery-3.3.1.min.js来说吧,压缩前266KB,压缩后85.1 KB。如果Web容器(tomcat etc.)启用GZIP压缩的话那么客户端下载的文件将会更小了。网上搜索常用的3个开源项目可供选择,最终选择Google Closure。别问我为什么,我是Google fans。哈哈。。。

三种工具为:

  1.Google Closure Compiler

  Google出品的JS代码优化、压缩、混淆工具。

  官网: https://developers.google.com/closure/compiler

  Github: https://github.com/google/closure-compiler

  2.Yahoo Yui Compressor

  Yahoo出品的JS代码压缩工具,可以压缩JS和CSS。同样网站需要压缩CSS,我后面会再写一篇关于CSS压缩。

  官网:http://yui.github.io/yuicompressor/

  3.UglifyJS

  官网: http://lisperator.net/uglifyjs/

       这个开源项目了解较少,不过网上有说JQuery就是使用此压缩工具。特别去jquery官网验证了确实是,在 JQuery Form 可以看到官方对UglifyJS的赞誉和推荐。原文:

One such tool is Mihai Bazon’s excellent UglifyJS. We’ve been using Uglify to compress jQuery, jQuery UI, and jQuery Mobile for nearly two years now, so if you’ve used any of our minified builds recently, you’ve benefited from Mihai’s work. 

       

       都是很厉害的项目,向各开源项目致敬。

       浏览了Google Closure Compiler的官网,官方仅明确的提供了http接口、UI压缩调用、在线压缩3中方式(见下面Google Closure的3种运行方式),没有直接调用Java API的方式介绍。网络搜索都是介绍怎么通过命令行脚本来压缩JS,因为系统开发模式的原因,我需要在本地调用Java API来压缩JS文件。

       既然这样我研究下命令行入口程序,看下main函数不就完了么。Github上看了下源码,初始化参数太多了较复杂,真不是一时半会时间的问题。Too young, too simple, too naive!!!

       转身搜了下stackoverflow还是没有,灵光想起Google Closure的Github项目WIKI,机智如我!果然就发现 一个FAQ : How do I call Closure Compiler from the Java API? 官方回复说没有调用Java API的官方教程和示例,不过有个博客上有精简的代码片段示例。当然想要更多细节,还是要研读入口程序 AbstractCommandLineRunner.java 和 CommandLineRunner.java 。

How do I call Closure Compiler from the Java API?

There's no official tutorial for the Java API. There's a short code snippet on this blog that, in our opinion, gives a nice 1-minute demo on how to do this.  ... ...

来源: how-do-i-call-closure-compiler-from-the-java-api

      

       看了博客感觉代码确实蛮诡异,不过测试结果正确可用。特别注意,在使用下面代码先了解其压缩模式,我整理了下见下面 Google Closure的3中压缩级别。例如我希望函数名称不能变,在保证可用性和压缩比的情况下只能选Simple模式。根据自己的需求去修改第10行代码:

    CompilationLevel.SIMPLE_OPTIMIZATIONS .setOptionsForCompilationLevel(options);

 

来源: calling-closure-compiler-from-java

/**

  * @param code JavaScript source code to compile.

  * @return The compiled version of the code.

  */

 public static String compile(String code) {

   Compiler compiler = new Compiler();

   CompilerOptions options = new CompilerOptions();

   // Advanced mode is used here, but additional options could be set, too.

   CompilationLevel.ADVANCED_OPTIMIZATIONS. setOptionsForCompilationLevel(

       options);

   // To get the complete set of externs, the logic in

   // CompilerRunner.getDefaultExterns() should be used here.

   JSSourceFile extern = JSSourceFile.fromCode("externs.js",

       "function alert(x) {}");

   // The dummy input name "input.js" is used here so that any warnings or

   // errors will cite line numbers in terms of input.js.

   JSSourceFile input = JSSourceFile.fromCode("input.js", code);

   // compile() returns a Result, but it is not needed here.

   compiler.compile(extern, input, options);

   // The compiler is responsible for generating the compiled code; it is not

   // accessible via the Result.

   return compiler.toSource();

}

 

Google Closure的3种压缩级别:

        在使用上面代码时,先了解Google Closure的3中压缩级别,分别为”Whitespace only”,”Simple”,”Advanced”。

      1)Whitespace only: 只是简单的去除空格换行注释。该等级的优化将移除代码中的注释,回车符,不必要的分号和空格,输出的Javascript等同于原有的Javascript;

      2)Simple:  该等级在A级的基础上,还对表达式和函数进行优化,包括重命名函数的局部变量和参数,缩短他们的名称。由于该等级重命名的变量都是作用域内(函数内),所与不会影响到优化的Javascript代码和其他的代码。该等级为压缩优化的缺省等级。例如,它会把函数内部变量名压缩修改为a、b、c,但是函数名称不会变。这也是其他压缩工具所使用的压缩方式,如UglifyJS等,也是最为主流的压缩方式比较安全;

      3)Advanced: 此级别的压缩改变(破坏)了原有代码结构,直接输出代码最终运行结果,而且这种级别的压缩还会删除未调用的函数代码。可见的确是分析,重写,变更代码,但是对代码压缩做到了极致,极大的减少了代码量。它从三个方面来压缩代码: i.more aggressive renaming(更多的重命名)除了重命名函数的局部变量和参数,还重命名全局变量,函数名,和属性。 如果JS代码不符合规范,可能导致压缩错误或优化后的代码不可用。

 

Google Closure的3种运行方式:

推荐这篇博客: JS代码压缩混淆工具使用说明,更详细的还是去看官网和github吧。