简体   繁体   中英

How to exclude an object from renaming in closure-compiler

I use closure-util and would like to have one object not renamed to change content in html.
In my first step I want to compile my modules together with openlayers 3|4..
I am not familiar with externs, export or api , so I need help in declaration for closure-compiler.

snippet .html (not compiled)

  olc.lon=7.11875;olc.lat=51.15345;olc.zoom=12;

snippet declaration in main.js will be compiled

var olc = {      // namespace controls and constants
  lon         :  2.0,lat: 25.0,rota: 0,zoom: 2, // as default
  debug       :  'force'
};
window['olc'] = olc;

Now after compiling
- olc.lon is renamed to olc.B,
- olc.lat is renamed to olc.uj,
- olc.rota is renamed to olc.mf,
- olc.zoom is not renamed, I don't know why not and
- olc.debug is not renamed.

Are there protected words like zoom ?
How can I protect olc.lon for example from renaming ?

Avoiding the Closure Type System

If you're using an object literal and you don't want to add any more type information, you can 'quote' the property names. This causes their values to be used directly and prevents them from being used as part of an inferred type (which may be optimized/replaced, as you've see).

// namespace controls and constants
var olc = {
  'lon'  : 2.0,
  'lat'  : 25.0,
  'rota' : 0,
  'zoom' : 2, // as default
  'debug': 'force'
};

This optimization is performed at a per-target/project level, not per-function, so the reasons that zoom and debug aren't replaced may have to do with where/how they and the other property names are used elsewhere in the program. You should not depend on this, it may change unpredictably. If you need zoom to remain as written, you must quote/protect it as you would lat and lon .

Using the Closure Type System

The Closure type system can be very useful, and avoiding it like this will prevent it from being able to detect some potential errors with these values. Instead, you could give the object/value an type in Closure's system which it will error-check, but knows not to rename.

There are regrettably many ways to do this, many of which depend on subtle combinations of Closure Compiler settings. (The documentation may tell you to use @exports , but even those don't work in some cases.) Here's the solution I use most often, because it works under most settings and is conceptually easy to understand: Define an external interface with the properties you need to have preserved, and apply it to your object.

You would define this interface type in an "externs file", which could be included in the build with the --externs flag if you're using the command-line (see "Declaring Externs" in the documentation ).

/externs.js
/** @interface */
function ControlsAndConstants() {}
/** @type {number} */
ControlsAndConstants.prototype.lat;
/** @type {number} */
ControlsAndConstants.prototype.lon;
/** @type {number} */
ControlsAndConstants.prototype.rota;
/** @type {number} */
ControlsAndConstants.prototype.zoom;
/** @type {*} */
ControlsAndConstants.prototype.debug;
/main.js
// namespace controls and constants
var olc = /** @type {ControlsAndConstants} */ ({
  lon  : 2.0,
  lat  : 25.0,
  rota : 0,
  zoom : 2, // as default
  debug: 'force'
});

window['olc'] = olc;

Notice that the property names aren't being quoted any more. We now want Closure to understand them, not ignore them.

Why does this work? The externs file tells Closure "This ControlsAndConstants interface already exists and is being used by code you don't compile. Because you can't optimize that code to rename the properties, you need to use the same property names yourself for compatibility." Simple enough!

Yes there are protected words, including any existing global variables (meaning any property of window object) and JavaScript keywords and probably more. Also anything in the standard "externs" that are included by default. I would need to research more why zoom and debug in particular are not renamed, but it is likely one of those categories.

There are a few ways to prevent renaming in closure compiler (and searching on that phrase would probably bring up lots more advice). One quick way to do it is to put property names in quotes like this:

var olc = {
  'lon': 2.0,
  'lat': 25.0,
  'rota': 0,
  zoom: 2,
  debug:'force'
};
window['olc'] = olc;

See is example of the online closure compiler on the above code .

You can also define your own "externs" to prevent properties being renamed. See the documentation about Advanced Compilation and Externs .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM