How to tell Closure Compiler to preserve properties on an object

时光总嘲笑我的痴心妄想 提交于 2019-12-24 00:38:41

问题


I have an object declared like this:

my.namespace.FEATURES = {
    FIRST_FEATURE = "first feature",
    SECOND_FEATURE = "second feature"
};

I use my.namespace.my.object to keep track of what kinds of features are available/implemented in my code. Every newly released version will have a modified set of features. A third-party using my minimized code will want to know what they can do in the version they have, so I supply the following function, which is exported, so that they know what they can do.

my.namespace.hasFeature = function(feature) {
    for(var prop in my.namespace.FEATURES) {
        if(my.namespace.FEATURES[prop] == feature) {
            return true;
        }
    }
    return false;
}

The problem is that the properties are getting renamed when I run Closure Compiler.

My question is: what's the best way to keep those properties preserved? I know I can export the property, but it feels kind of dirty for some reason. Is there a Closure best practice to preserve the properties of an object?


回答1:


Exporting is there for a reason - as a directive to the Closure library that this is used by outside agents so it should not be renamed. The sections here on exporting explain how you can force Closure to keep a symbol intact (with no renaming). You mostly just need to follow the directions here. There is nothing "dirty" about exporting. It is there for exactly what you need - to tell Closure that this symbol is used by an external agent and cannot be renamed.

The other trigger that can keep Closure from renaming a property is if it is accessed by a string like this:

var f = "FIRST_FEATURE";
my.namespace.FEATURES[f] = "first feature";

In that case Closure sees that your code is using strings to address a property and (since it never messes with string values) it realizes that it can't rename the FIRST_FEATURE property safely.




回答2:


The Closure Compiler has JavaDoc style markup...
Here's the page referencing the markups: Annotating JavaScript for the Closure Compiler
To retain a field name, place /** @expose */ before the field declaration.

my.namespace.FEATURES = {
    /**@expose*/
    FIRST_FEATURE: "first feature",
    /**@expose*/
    SECOND_FEATURE: "second feature"
};

... if you need to retain the namespace, it's the same concept...

/**@expose*/
my = my || {};
/**@expose*/
my.namespace = my.namespace || {};
/**@expose*/
my.namespace.FEATURES = {
    /**@expose*/
    FIRST_FEATURE: "first feature",
    /**@expose*/
    SECOND_FEATURE: "second feature"
};

In addition to retaining the filed name, it also allows you to reference that field using dot-notation later in your code. Using obj["field"], the compiler will lose the reference if you call it with obj.field later instead of having to use strings.




回答3:


In ADVANCED mode simply quoting the keys tells the compiler not to renamed them:

my.namespace.FEATURES = {
    'FIRST_FEATURE' : "first feature",
    'SECOND_FEATURE' : "second feature"
};

Useful information about property renaming:

https://developers.google.com/closure/compiler/docs/api-tutorial3

https://github.com/google/closure-compiler/wiki/FAQ#some-of-my-properties-are-getting-renamed-but-some-arent-why



来源:https://stackoverflow.com/questions/9659810/how-to-tell-closure-compiler-to-preserve-properties-on-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!