I'm looking for a way to strip out debug code from functions so I can add test hooks to closures. I've read Google Closure Compiler advanced: remove code blocks at compile time and tested out removing debug code with the following:
/** @define {boolean} */
var DEBUG = true;
if (DEBUG) {
console.log('remove me');
}
Simple optimisation with --define='DEBUG=false'
reduces this to var DEBUG=!1;
. The same applies for this:
/** @const */
var DEBUG = false;
if (DEBUG) {
console.log('remove me');
}
Where I run into trouble is using this convention inside a function:
/** @const */
var DEBUG = false;
function logMe() {
if (DEBUG) {
console.log('remove me');
}
}
This reduces to the following:
var DEBUG=!1;function logMe(){DEBUG&&console.log("remove me")};
I would expect it to reduce further to:
var DEBUG=!1;function logMe(){};
Is there a reason this is not working as expected? I'm really just looking for a clean way to strip debug code and am not ready to take the plunge into advanced optimizations.
Update
Per @John's answer, I implemented my own compiler and have found that the following configuration will remove if (DEBUG) {}
from inside and outside the code for the case of a @define
:
CompilerOptions options = new CompilerOptions();
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
//options.setInlineConstantVars(true);
options.setInlineVariables(CompilerOptions.Reach.ALL);
options.setDefineToBooleanLiteral("DEBUG", false);
This works well enough for a single file with the following limitations:
var DEBUG
to be defined in each file, which is bad practice.var DEBUG
or the compiler can't optimize around it. This could be avoided by compiling each file individually and merging them.I've toyed with the idea of removing all var DEBUG
definitions from the files and injecting it into the source or extern before execution, but I've run into two issues:
DEBUG
in the uncompiled code throws a reference error in the browser.The ideal option would be to test window.DEBUG
, which does not throw a reference error. Unfortunately, while injecting /** @const */ var window = {}; /** @const */ window.DEBUG = false;
works at the top level, reducing if (window.DEBUG) {}
, the optimization is actually reverted if placed in a function.
Unless another compiler option works the only option that would really make sense is to go with window.DEBUG
and before compilation inject /** @const */ var DEBUG = false;
and to a global replace of /\bwindow.DEBUG\b/
with DEBUG
. Is there a better way?
The Closure Compiler is a tool for making JavaScript download and run faster. Instead of compiling from a source language to machine code, it compiles from JavaScript to better JavaScript. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left.
Solution(By Examveda Team) In Advanced mode, the Closure Compiler rewrites the JavaScript by renaming variables and functions from longer descriptive names to single letters to save file size, and it inlines functions, coalescing them into single functions wherever it determines that it can.
The value of this parameter indicates the degree of compression and optimization to apply to your JavaScript. There are three possible compilation levels: WHITESPACE_ONLY , SIMPLE_OPTIMIZATIONS , and ADVANCED_OPTIMIZATIONS .
Use @define annotation:
@define {boolean}
DEBUG = true;
And compile with option
--define="DEBUG=false"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With