用于格式化JavaScript文件的任何高性能Java API?

时间:2016-12-14 12:47:47

标签: java multithreading google-closure-compiler

我的Web项目中有超过2000个JS文件要格式化。我知道谷歌封闭编译器擅长这样做,实际上我用它来编写整个JS文件格式的工具。我的要求是格式化的JS文件将在同一个地方替换原始文件。

我写了一个Java程序来查找web项目中的每个JS文件,当找到一个文件时,一个线程将负责执行命令

java -jar compiler.jar --js C:/project/xyz/abc.js --js_output_file C:/project/xyz/abc.js`

原始JS文件(abc.js)将被格式化。

但我发现这种方式效率不高。问题是我使用ExecutorService来运行线程,每个线程需要大约10秒来完成文件的格式化。所以你可以想象完成超过2000个文件需要多长时间。

以下是代码段。

ExecutorService executor = Executors.newFixedThreadPool(10); 
// ...
for(File jsFile : root.listFiles()) {
  Runnable formatThread = new FormatThread(jsFilePath.getAbsolutePath()); 
  //execute command "java -jar compiler.jar in run(), handled by ProcessBuilder
  executor.execute(formatThread);
}

我尝试增加线程池大小,但程序启动后CPU和内存很快就消耗殆尽了。

我的问题是

  1. 用Java编写的应用程序格式化大量文件的有效方法是什么?
  2. 我的程序中ExecutorService的使用是否正确且适合我的用例?
  3. 任何其他Java API都可以快速格式化Javascript文件?实际上我需要的只是删除空行和用户注释,但不需要压缩文件。

1 个答案:

答案 0 :(得分:1)

通过命令行启动所有这些任务会产生巨大的开销,因为它还需要启动一个新的jvm。

您可以从jar清单表单java代码中运行主类的main方法(afaik com.google.javascript.jscomp.CommandLineRunner):

for(File jsFile : root.listFiles()) {
    Runnable formatThread = () -> com.google.javascript.jscomp.CommandLineRunner.main(new String[] {"--js", jsFilePath.getAbsolutePath(), "--js_output_file", jsFilePath.getAbsolutePath()}));
    executor.execute(formatThread);
}

甚至可能有一种更有效的方式来调用API ......

修改

最好以不同的方式调用API。 e.g。

CompilerOptions options = new CompilerOptions();
CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
options.setCheckGlobalThisLevel(CheckLevel.OFF);
options.setOutputCharset("utf-8");
com.google.javascript.jscomp.Compiler compiler = new com.google.javascript.jscomp.Compiler(System.err);
compiler.disableThreads();
compiler.compile(SourceFile.fromFile(externsFile),
        SourceFile.fromFile(jsFile),
        options);
String result = compiler.toSource();
// TODO: write result to file