使用Google Closure Compiler校验、压缩js代码

背景

项目中需要对js代码进行语法校验、编码转换与代码压缩。以前的做法是,对https://closure-compiler.appspot.com/compile (一个在线js压缩网站)进行http post请求并获取response来实现,但该方法(由于某些原因)经常请求失败,且到生产环境就行不通了。后来发现一个谷歌的jar包也能实现该功能,故分享之。

如何使用

1、引入maven依赖:

    <dependency>
        <groupId>com.google.javascript</groupId>
        <artifactId>closure-compiler</artifactId>
        <version>v20180204</version>
    </dependency>

2、代码实现:

   /**
   * 校验js语法、压缩js
   * @param code
   * @return
   */
    public static String compileJs(String code){
        if (StringUtils.isBlank(code)) {
            CheckUtil.throwCustomException(ErrorCode.CARD_COMPILE_FAIL, "卡片js代码为空!");
        }

        Compiler compiler = new Compiler();

        CompilerOptions options = new CompilerOptions();
        // Simple mode is used here, but additional options could be set, too.
        CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);

        // To get the complete set of externs, the logic in
        // CompilerRunner.getDefaultExterns() should be used here.
        SourceFile extern = SourceFile.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.
        SourceFile input = SourceFile.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.
        if(compiler.getErrorCount() > 0){
            StringBuilder erroInfo = new StringBuilder();
            for(JSError jsError: compiler.getErrors()) {
                erroInfo.append(jsError.toString());
            }
            CheckUtil.throwCustomException(ErrorCode.CARD_COMPILE_FAIL, erroInfo.toString());
        }
        return compiler.toSource();
    }

三种压缩模式介绍

  • Whitespace only:只是简单的去除空格换行注释。

  • Simple:比Whitespace only更高端一点,在其基础上,还对局部变量的变量名进行缩短。这也是其他压缩工具所使用的压缩方式,如UglifyJS等,也是最为主流的压缩方式。比较安全。

  • Advanced:Advanced级别的压缩改变(破坏)了原有代码结构,直接输出代码最终运行结果,而且这种级别的压缩还会删除未调用的函数代码。

注意:Advanced级别的压缩虽然对代码压缩做到了极致,但也改变(破坏)了原有代码结构,直接输出了代码最终运行结果,所以使用起来得异常小心,稍微有不规范可能就会引起压缩报错或者压缩成功后却不能正常运行。