org.wicketstuff.closurecompiler.ClosureCompilerJavaScriptCompressor Maven / Gradle / Ivy
package org.wicketstuff.closurecompiler;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.javascript.IJavaScriptCompressor;
import org.apache.wicket.util.lang.Args;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.javascript.jscomp.CommandLineRunner;
import com.google.javascript.jscomp.CompilationLevel;
import com.google.javascript.jscomp.Compiler;
import com.google.javascript.jscomp.CompilerOptions;
import com.google.javascript.jscomp.Result;
import com.google.javascript.jscomp.SourceFile;
/**
*
* create a javascript compressor based on google's closure compiler.
*
* due to the amount of cpu used by closure compiler the generated javascript should definitely be
* cached, e.g. using resource caching in wicket 1.5.
*
* @author Peter Ertl
*/
public class ClosureCompilerJavaScriptCompressor implements IJavaScriptCompressor
{
private static final Logger log = LoggerFactory.getLogger(ClosureCompilerJavaScriptCompressor.class);
private CompilationLevel level;
public ClosureCompilerJavaScriptCompressor()
{
level = CompilationLevel.SIMPLE_OPTIMIZATIONS;
}
public CompilationLevel getLevel()
{
return level;
}
public void setLevel(CompilationLevel level)
{
this.level = Args.notNull(level, "level");
}
@Override
public String compress(String uncompressed)
{
try
{
return compressSource(uncompressed);
}
catch (Exception e)
{
log.error(e.getMessage(), e);
return uncompressed;
}
}
public final String compressSource(String uncompressed) throws Exception
{
// environment for compilation
final List externs = CommandLineRunner.getBuiltinExterns(CompilerOptions.Environment.BROWSER);
// create compiler + options
final Compiler compiler = new Compiler();
final CompilerOptions options = new CompilerOptions();
level.setOptionsForCompilationLevel(options);
// never remove unused stuff:
// this only would work when we had all javascript for the page bundled together
// also this will not work due to the dynamic rendering of javascript after page creation
options.removeUnusedVars = false;
options.removeUnusedLocalVars = false;
options.removeUnusedPrototypeProperties = false;
// custom configuration options
configure(compiler, options, externs);
// TODO integrate logging into slf4j
// input sources
final List inputs = new ArrayList<>();
inputs.add(SourceFile.fromCode("custom", uncompressed));
// compile input
final Result result = compiler.compile(externs, inputs, options);
if (result.success == false)
{
throw new ClosureCompilationException(result.errors);
}
return compiler.toSource();
}
protected void configure(Compiler compiler, CompilerOptions options, List externs)
{
// for overriding + configuring
}
}