4 ms·
How can it determine dead code for such a dynamic language like JavaScript? Is it limited to obvious stuff like things after a "return;" statement that cannot
by Drakim 11y ago
How can it determine dead code for such a dynamic language like JavaScript?
Is it limited to obvious stuff like things after a "return;" statement that cannot run? Because I don't see how it could remove unused functions when you can invoke them in such indirect ways: myobj['f'+'oo']();
- lclemente 11y agoThey explain it here: https://developers.google.com/closure/compiler/docs/limitations https://developers.google.com/closure/compiler/docs/limitati...
- sgrove 11y agoYou have to restrict your code to a certain style (and there are warnings for whenever you're defeating the DCE, I believe). You'll particularly see this when you're accessing properties via array-index-like lookup (your myObj['f'+'oo']) example) instead of e.g. myObj.foo under advanced compilation, where the property name will have been munged and doesn't exist. Like anything else, there are tradeoffs, and Closure asks that you restrict yourself to a more predictable set of patterns in return for the benefits it offers.
- rav 11y agoThis kind of indirection is specifically not supported even with simple optimizations: https://developers.google.com/closure/compiler/docs/limitations#restrictions-for-simple_optimizations https://developers.google.com/closure/compiler/docs/limitati...
- dahart 11y agoYou tell the compiler a file that it's not allowed to dead-strip. From there, it then computes the transitive closure of the rest of your code that is referenced from the "entry point", and removes everything else. It is, of course, possible to reference things in indirect ways that the compiler can't see, so they provide some mechanisms to force inclusion if necessary.
- reitzensteinm 11y agoYou have to follow a set of rules - your example would not be allowed. One of the nice things about ClojureScript is that the compiler will output compatible code, so you don't even really have to think about it (except when doing JS interop). If you write valid ClojureScript, it Just Works.
- teamhappy 11y agofunction add(a,b) { return a+b } console.log(add(1,2)) Compiles to console.log(3) I'm not sure about your example, but I think it would work. (Apparently not)
- mythz 11y agoHave a look at the advanced compilation option: https://developers.google.com/closure/compiler/docs/api-tutorial3?hl=en https://developers.google.com/closure/compiler/docs/api-tuto... Basically when enabled it will rewrite normal property access, e.g: `myObj.foo` to something like `a.b` but wont shorten string literal access, e.g `myObj['foo']` just becomes `a.foo` which you would use for any API's you want to export. For a real-world example I use string literals for declaring jquip's public API: p['removeAttr'] = function(name){ return this['each'](function(){ if (this.nodeType == 1) this.removeAttribute(name); }); }; Which closure advanced rewrites to: q.removeAttr=function(a){return this.each(function(){this.removeAttribute(a)})}; Original: https://github.com/mythz/jquip/blob/master/dist/jquip.all.js https://github.com/mythz/jquip/blob/master/dist/jquip.all.js Compiled: https://github.com/mythz/jquip/blob/master/dist/jquip.all.closure-advanced.js https://github.com/mythz/jquip/blob/master/dist/jquip.all.cl...
- nunull 11y agoMay i ask why you are using this notation? I honestly can't think of any benefits. Isn't it more convenient and readable to use `p.removeAttr`?
- mythz 11y agoMy comment explains the entire purpose for using it - if I didn't, it would've got rewritten into `a.b` and none of the public API's would work!
- eschutte2 11y agoI wish there were a better way to indicate which properties were renameable, because I need this too and I'm not willing to go as far as you did.
- Shebanator 11y agothere is a much better way to deal with this: https://developers.google.com/closure/compiler/docs/api-tutorial3#externs https://developers.google.com/closure/compiler/docs/api-tuto...