How to save global variables in javascript when using the Closure compiler with advanced optimization?

I have my own Javascript library that I want to minimize by using the Google compiler of closure with advanced optimization. Looking at the docs , I see how to declare functions that are used outside the library.

However, I could not find a way to save global variables declared in my library. The Closure compiler simply deletes them because it believes that they are never used. Can anybody help?

Edit: sample code:

var variable_1 = true; 

This is defined globally to the right at the beginning of my library, but has never been used in the library itself. It is used outside the library when it is included on any page. But the Closure compiler does not know, and it is for this reason that it removes these declarations.

+4
source share
3 answers

The closure compiler cannot remove global variables declared as window["variable_1"] = true

I recommend that you write directly to window for global variables, and I also recommend using string literals for your variable names so that closing does not reduce it.

+7
source

Although you can reference a "true" global variable by replacing all use of this global variable with window["varname"] , it is generally not recommended to "pollute" the global namespace. The Closure compiler is designed to prevent you from doing this.

CAVEAT : window["varname"] and var varname do not match, since the "window" may not always be a global object in non-working environments. In essence, the Closure Compiler assumes that the global object and the window are different. For example, window["varname"] will compile with window.varname instead of var varname . They are NOT the same, although they work similarly in the browser.

It is best to create a global namespace object and then export only one object. All your β€œglobal” variables should become properties in this global namespace variable. Benefits:

  • All these global variables are renamed to shorter versions.
  • Constants may be nested
  • The Closure compiler automatically "aligns" the namespace anyway, so your code will not be slower.
  • Excellent obfuscation
  • Your code also works in non-browser environments. Remember that a window may not always exist (for example, on the server side), and a global object may not always be a window

If you have global variables that the user must read / set to use your library, this is also discouraging. It is better to set the API for the global namespace object, and then publish the API as usual through the window object: window["myLib"]["setConfig"] = myLib.setConfig .

In your case, if you have global variables used in other parts of your code that are not related to Closure-Compiled, you should consider:

  • Is it better to place the declaration of these variables outside the file compiled by Closure
  • Why don't you put the declaration of these variables along with code that uses them.
  • If you really are a Closure compilation of all code instead of a part (maybe? Are you using a different library?)
+2
source

I just stumbled upon this, and I have my own solution.

Create the entire library as part of the self-executing function, placing all the properties of the object as strings (at least once for each property) as follows:

 (function () { var myLibrary = { 'myMethod' : function () { ... } } myLibrary.myMethod['propertyOfTheMethod'] = ''; }()); 

The usual way to make this accessible from the outside would be to put var myLibrary = before the function and return myLibrary at the end of it so that it is assigned to a global variable. But the function is executed in the global scope (since it is executed independently), so we can create the this property using a string literal. So completely:

 (function () { var myLibrary = { 'myMethod' : function () { ... } } myLibrary.myMethod['propertyOfTheMethod'] = ''; this['myLibrary'] = myLibrary; }()); 

But this will not work under "use strict"; . The best way to get a global variable in strict mode is with var global = Function('return this')(); , and then assign it a variable.

0
source

All Articles