0

I have a class that has roughly this structure:

function MyClass() {
    // constructur stuff
}

MyClass.prototype.myFunc = function () {
    // example function
};

MyClass.myStaticFunc = function () {
    // example static function
};

I spent some time now setting up the closure compiler annotations and finally got rid of all warnings. And what do you know, it reduces the size by a spectacular 100%. So then I read about exporting functions, but window['MyClass'] = MyClass will only export the constructor. To be honest, I'd rather not export every single method individually. I thought the compiler would export and not obfuscate all publicly available methods but those with a @private annotation.

What's the best way to teach the closure compiler to do that and not have to export every method individually?

Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100

2 Answers2

2

Using ADVANCED_OPTIMIZATIONS you must export EVERY public method and property. If you do not want the public methods and properties renamed, then use SIMPLE_OPTIMIZATIONS.

See my Which Compilation Level is Right for Me post for more details.

Chad Killingsworth
  • 14,360
  • 2
  • 34
  • 57
  • But the advanced options do much more than that, which is why I want to use them. Anyhow, using the export annotation worked like a charme (see my own answer). – Ingo Bürk Apr 15 '13 at 17:48
  • Advanced Optimizations does dead-code removal on the global space. That's the only other major difference. – Chad Killingsworth Apr 15 '13 at 18:40
1

I believe I found the answer: I can annotate methods with @export and run the compiler with --generate_exports. But maybe someone has an even better way.

Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100
  • `@expose` is your "better" way. – Chad Killingsworth Apr 15 '13 at 18:40
  • Could you explain why it is better than @export? @expose will prevent any optimization, which is definitely bad. And as the docs say: "@expose should never be used in library code" – Ingo Bürk Apr 16 '13 at 06:33
  • That statement is there because `@expose` prevents renaming and dead code elimination. It is "better" than `@export` because it doesn't require a special flag at compilation time. Of course if you are writing a library for others to consume, then you should be using neither in the main code. Exports should be at the end of the code or better in a separate file because they block renaming and dead code elimination. – Chad Killingsworth Apr 16 '13 at 13:25
  • Why does `@export` block renaming? I can't see that happening in my output, it seems to work just fine. As for dead code elimination, I can't tell right now, because I don't have dead code (yet). The way I understand it, `@exports` should be equivalent to "manually" exporting methods, which, by the way, I'm trying to avoid, as I don't like the idea of having exports somewhere else in the code (error-prone); annotations I see right where I write my method. – Ingo Bürk Apr 16 '13 at 14:05
  • Also: I don't mind the additional compiler flag. That's what they're there for ;) – Ingo Bürk Apr 16 '13 at 14:06
  • 1
    `@export` both renames the property and preserves an reference to the original name - producing code similar to `foo.a=1;foo['prop']=foo.a;`. `@export` produces `foo.prop=1`. If you have lots of internal references to `foo.prop`, then `@export` will produce smaller gzip results. If `foo.prop` is mainly for external consumption, then `@expose` will produce smaller results. This is why I put better in quotes - it depends on usage. – Chad Killingsworth Apr 16 '13 at 15:17
  • Alright, thank you. I might compare them sometime, but for now I'm going with `@export`. :) – Ingo Bürk Apr 16 '13 at 16:48
  • 3
    `@expose` is now deprecated. `@export` is now officially the correct method. – Chad Killingsworth Apr 17 '15 at 15:42
  • I ran through a few experiments here: http://www.syntaxsuccess.com/viewarticle/using-the-closure-compiler---advanced_optimizations – TGH Dec 04 '16 at 06:03