I'm trying to get the Google Closure Compiler to not rename objects when passed as settings or data to a function. By looking at the annotations present in jQuery, I thought this would work:
/** @param {Object.<string,*>} data */
window.hello = function(data) {
alert(data.hello);
};
hello({ hello: "World" });
However, it ends up like this:
window.a = function(b) {
alert(b.a)
};
hello({a:"World"});
The ajax
function found here has this annotation and it appears to work. So, why won't this? If data is the return value from an external source or a settings object I'd like to be able to tell the compiler to not touch it, using the this["escape"]
trick is to intrusive for something like this in my opinion.
function ajax(success) {
// do AJAX call
$.ajax({ success: success });
}
ajax(function(data) {
alert(data.Success);
});
Output:
$.b({c:function(a){alert(a.a)}});
success
has been renamed to c
and Success
(with a capital S) has been renamed to a
.
I now compile the same code with the jQuery 1.6 externs file and get the following output:
$.ajax({success:function(a){alert(a.a)}});
It also produces a warning that the property Success
is not defined, as I would expect, but it cannot rename Success
to simply a
, that will still break my code. I look at the annotation present for the ajax
and I find this type expression {Object.<string,*>=}
, I annotate my code accordingly, and recompile. Still not working...
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 Closure Compiler provides special checks and optimizations for code that uses the Closure Library. In addition, the Closure Compiler service can automatically include Closure Library files. Finding Your Way around Closure describes the syntax for declaring the parts of Closure that you need.
Since your focus seems to be on the source rather than the output, it seems like what you're focused on is DRY (Don't Repeat Yourself). Here's an alternative DRY solution.
You can run the Closure Compiler with --create_name_map_files
. Doing so emits a file named _props_map.out
. You can have your JSON-emitting server-side calls (ASP.Net MVC or whatever it might be) use these maps when emitting their JSON, so they're actually emitting minified JSON that leverages the renames the Closure Compiler performed. This way you can change the name of a variable or property on your Controller and your scripts, add more, etc, and the minification carries through from the scripts all the way back to the Controller output. All of your source, including the Controller, continues to be non-minified and easy to read.
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