-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Module design for optimal minification #86
Comments
@frankebersoll Please see issue #71. I use this feature to build TsProject. Essentially, it provides a namespace to allow for exported (public) classes. Classes outside this "package" are treated as internal so that the minifier shortens pretty much all identifiers in these "internal" classes. This is a huge win for minifying TypeScript code. |
@frankebersoll Additionally, by convention all classes that are not "exported" ( int the generated bundle source file ) are treated as internal by the minifier. The bundler uses the bundle package configuration settings to decide when to remove the "export" keyword from the project source files. |
@ToddThomson, I haven't had a chance to take a look into this yet, but we mark everything as public / private / internal. Those that are not marked public should be mangled. From these discussions it sounds like that may not be the case. Is this true? Thanks for your time. |
@niemyjski No that is not the case. All private method and property names are shortened. The problem is that TypeScript does not have an internal modifier for classes. So the solution is to find a convention that allows for a package to have a pseudo set of internal classes. I chose to do this with a package "namespace". Anything inside the package namespace and TsProject will treat as external ( Essentially the API ). Note that anything non public will still be mangled. |
Reference to issue #66 |
@frankebersoll @niemyjski Let me know when you've got an understanding of how TsProject currently separates the public and internal API for a bundle. I'm pretty sure that TypeScript 1.8.9 (or greater) with namespace merging together with TsProject "packaging" should work for you. However, I can always update the feature if required. |
@frankebersoll @niemyjski I am currently looking at using a comment transform directive to override when an identifier may be mangled. For example |
@frankebersoll @niemyjski Please let me know if you are still interested in this issue. I am going to be making changes to the "packaging" feature of TsProject over the next couple of weeks and would welcome your input on what you require in this area. |
Yes, this would be something I'd be interested in, ideally it would be controlled via the access modifiers and you wouldn't have to do anything. |
@niemyjski The minifier utilizes the Typescript AST and examines identifier flags for access modifier flags. This yields a bit better results then uglifyjs. However, for optimal minification there are conventions that can be used to make more of the bundle/package "internal" and thus even public identifiers can be mangled. This results in much better minification than uglify.js. However, there are situations where this extra optimization runs into trouble. Angular bindings for example. This is where adding annotations to identifiers can work really well. Essentially we apply additional type information by using an annotation within a comment above the identifier. For example: BTW: Please give me your thoughts on issue #99 . This will effect you. |
Yeah, I think an annotation within a comment would be good or maybe even an annotation (no comment). I'm not sure @frankebersoll is available anymore :( I haven't heard from him in months. I'll take a look at #99 |
@frankebersoll I am interested in talking to you about your initial comment. I am now actively looking at at minification analysis. Although it will be applied to TsMinifier TsProject used a basic convention to make non exposed API private and non exportable. This will change substantially in TsMinifier. I will detail the new feature in that repo. |
One question about minification in general: How can we design our modules so that only a well-defined public api surfaces unmangled? Our project has an
ExceptionlessClient
that can be configured with plugins and depends on several services. It might be desirable to have a minimal-size version of the library for users that have no interest in extending any of its inner workings, so most of the names could be mangled. But then, I couldn't figure out how to achieve that.Currently, we have many typescript files that each export one or many classes, like this:
A user would reference the client class like this
var client = require("exceptionless").ExceptionlessClient
and then use it. Everything public inExceptionlessClient
andEventBuilder
belongs to the public API and obviously shouldn't be mangled. Now, the defaultConfiguration
instance adds many plugins that themselves use other components. All those things could easily be mangled, which would save us lots of code. They don't even need to be exported.Which type names or member names should be mangled and which shouldn't could be manually specified in the tsproject.json. Or there could be some sophisticated analysis that starts with a defined class or namespace and walks all visible types recursively to find all public names. Maybe there already is some mechanism that I don't know about, yet.
I would also like to assist in building such a feature, maybe you can point me to the right direction.
Thanks for your help!
The text was updated successfully, but these errors were encountered: