microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
99.14k stars 12.3k forks source link

Suggestion: minification #8

Closed RyanCavanaugh closed 1 year ago

RyanCavanaugh commented 9 years ago

TypeScript should support emitting minified JavaScript.

There are several different things we could support:

  1. Just remove whitespace
  2. Minify unobservable identifiers
  3. Remove provably dead code
  4. Whole-program minification (i.e. closure compiler)
  5. (Others?)
chaser92 commented 9 years ago

I think that this isn't the best idea - TypeScript should better do what it's best at, one tool should serve one purpose. There are a lot of great minifiers out there.

NoelAbrahams commented 9 years ago

@chaser92, this request is to minify TypeScript code, not JavaScript code. A minifier that uses the information (primarily information on access modifiers) available to the TypeScript compiler will be much more efficient than any JavaScript minifier out there.

I am personally very eager to see this implemented.

RyanCavanaugh commented 9 years ago

Motivating examples of things that TypeScript could minify but an external minifier could not would be useful. Things like closure and uglify do a really good job already; we'd have to have evidence we could make real improvements over them to justify spending time on it.

NoelAbrahams commented 9 years ago

The following TypeScript code

class Greeter {

    private greeting: string;

    constructor (message: string) {
        this.greeting = message;
    }

    public greet() {
        console.log(this.getMessage());
    }

    private getMessage() {
        return "Hello, " + this.greeting;
    }
}

Can be compiled into JavaScript that when run through an external minifier results in the following:

var Greeter = (

    function () {

        function a(b) {
            this.greeting = b
        }

        a.prototype.greet = function () {
            console.log(this.getMessage())
        };

        a.prototype.getMessage = function () {
            return "Hello, " + this.greeting
        };

        return a
    }
)();

Problems:

In summary, even in just this simple snippet of code TypeScript can improve on an external minifier, both by mangling names that should have been minified as well as optionally leaving names untouched.

RyanCavanaugh commented 9 years ago

If I use the Closure Compiler, it goes from code like this:

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        console.log(this.getMessage());
    };

    Greeter.prototype.getMessage = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

var x = new Greeter();
x.greet();
console.log(x.getMessage());

to this:

var b = new (function() {
  function a(a) {
    this.c = a;
  }
  a.prototype.b = function() {
    console.log(this.a());
  };
  a.prototype.a = function() {
    return "Hello, " + this.c;
  };
  return a;
}());
b.b();
console.log(b.a());

Here, the greeting field and getMessage names have been correctly minified. The "over-minification" of other variables leads to my next discussion point on this.

Some people think class names, property names, parameter names, local names, etc are meaningful runtime metadata, other people think they're not. Some other people think only some of their property names, parameter names, local names, and so on are things that should be minified. Among those people, there's disagreement over how those names should be specified (globally? locally? in the code? in a config file? on a commandline?). Nearly everyone believes that their set of rules is the only one that makes sense.

The only path forward that could beat existing minifiers also involves a ton of configuration for what the allowed set of minifications even is; implementing and testing all these rules would be very expensive. It's a lot of investment for what is probably a few percent improvement (especially after gzipping) over the state of the art here. That's why we want to see compelling examples for where only the TypeScript compiler could minify and do a meaningfully better job than any existing tool.

NoelAbrahams commented 9 years ago

@RyanCavanaugh,

Regarding the under-minification problem, it looks like the code in your post was minified using the "advanced" option of the closure "compiler". And yes, that appears to solve the problem in this simple case. However, consider this slightly more involved example:

class Greeter {

    public greet() {
        console.log('greet');
    }
}

function createInstance<TType>(name:string): TType {

    return new window[name]();
}

var x = createInstance<Greeter>('Greeter');
x.greet();

Basically, we have introduced a class factory function. The closure compiler, with the advanced option, minifies this to

(function() {
  function a() {
  }
  a.prototype.a = function() {
    console.log("greet");
  };
  return a;
})();
(new window.Greeter).a();

Clearly this is going to fail at runtime. The solution is to export the "Greeter" symbol:

window["Greeter"] = Greeter;

Seems simple enough. But in large projects with hundreds of classes, this is not trivial. TypeScript understands this code better, because it knows that function Greeter is a class name.

More importantly, the problem I have with the closure compiler is that it requires the entire code-base to be minified in one go. This is not feasible in large projects, where there is separation between library code and client code. In this situation it is necessary to declare externs, which ultimately results in maintaining one's public API in duplicate.

With regard to the second issue that was raised, namely the problem of configuration, that, I guess, is an implementation detail: if there is demand for configuration then that would have to be dealt with. But it seems strange to decline an entire issue on that basis.

A possible halfway solution would be for TypeScript to provide an option to generate closure-style extern files or to export symbols (class names).

danquirk commented 9 years ago

The configuration is not just an implementation detail. The fact that we can go back and forth all day with different code examples that need differing amounts of minification is proof of the need for either a) very simple minification algorithms b) extremely customizable minification options. You've already identified multiple issues that absolutely demand customization to work at all.

In addition, we're still talking about this nebulous concept of 'the TypeScript compiler understands the code better so it should just do this example correctly' (for some definition of correctly). There's still very little here that is actually stating proposed solutions to classes of problems which you could put a configuration over the top of.

NoelAbrahams commented 9 years ago

To summarise the discussion so far:

In the light of the above, I have three basic proposals listed in order of preference:

A. A fully functional minifier provided by TypeScript. We provide two compiler options

In both cases, private fields and methods would always be minified.

B. TypeScript generates externs files for providing to the Closure Compiler if specified.

C. TypeScript only minifies private fields and methods if specified.

It is conceivable that with option A there will be many people who would like a halfway solution between "simple" and "advanced" minification, e.g. preserve class names but minify constructor signature. In this instance, it may be possible for those concerned to run the output generated by TypeScript through a third-party minifier that provides more specific options.

ghost commented 9 years ago

I like your B suggestion (TypeScript generates externs files for providing to the Closure Compiler). Not sure how it works but I like the sound of it when considering the points that everyone else is making.

bryanerayner commented 9 years ago

TL;DR Perhaps Data-Annotations could be added to Typescript's syntax to provide developers with an easy way to tell the compiler what should, and should not be overly minified.

I have been writing a large Angular app using Typescript. I've been painfully watching the size of the JS grow and grow, and would personally LOVE to have some advanced compilation support that only Typescript can provide. IMO Typescript can do an incredibly good job at minifying code, better than closure because you're not limited to comments for specifying compiler directives.

For an Angular app, there needs to be a high level of granularity of what functions and properties are minified (a la Closure Compiler's advanced mode) and what properties should be left as-is. They are referenced in the HTML and oftentimes used by Angular to correctly link the DOM to JS. You'd need a solution on an item by item basis in order to accomplish this in a way that would make it easy to use.

For example, much in an Anuglar directive can be truly 'Javascript Only', and I would like advanced minification on it. However, there are some variables that need to be exposed to HTML, outside of the javascript engine.

If we were able to use something similar to a C# data-annotation on class properties, that would be a much better method than Closure compiler's recommendations. I've seen a lot of Javascript written for the Closure compiler that uses array notation to reference unminified properties - This is a pain to write. Any time you reference a property by a string in Javascript, it just feels muddy to me.

I've been using Newtonsoft.Json on a dot Net backend. We directly serialize our business logic models to the client side - Of course, we want to keep some things hidden from JSON serialization. For those without a C# background, a data annotation looks like this:

Imports Newtonsoft.Json

class Klass
{
    [JsonIgnore]
    public string[] SomethingVeryLarge;

    public string SomethingMoreManageable;
}

The [JsonIgnore] data annotation instructs Json.Net to overlook this property when parsing an instance of Klass.

Having something like data-annotations could provide the compiler with a really good system of flags, that could be used for this advanced minification support, or other compiler features. I could see this syntax eventually being usable Typescript programs to further extend the language.

NoelAbrahams commented 9 years ago

@bryanerayner,

there are some variables that need to be exposed to HTML, outside of the javascript engine.

Yes, that's a relevant point as well. This is also the case when using KnockoutJS, for example:

class ViewModel {

  [minifyIgnore]
  public foo = ko.observable('bar');
}

because foo is referenced in the HTML:

<div data-bind="text:foo" />
eggers commented 9 years ago

I would love a typescript aware minifier. Also, because I've had some issues with ng-min not working very well on tsc generated javascript. (I haven't tried ng-annotate yet)

WanderWang commented 9 years ago

I Agree with @RyanCavanaugh I'm working for a Open Source HTML5 Game Framework called EGRET Many of our developers thinks that our game.min.js should be smaller and smaller . Now we compress our game.min.js with Google Closure Compiler SIMPLE_OPTIMIZATION , there are some reason we abandon ADVANCED_OPTIMIZATION

So, I hope both B and C could be added to tsc . By the way ,forgot A ,please ^_^

mirhagk commented 9 years ago

I'm noticing that the problem with using Closure is that there is information about visibility that TypeScript is aware of that Closure can't know.

This is why the private members stick around when using simple with Closure. Using advanced can cause headaches.

TypeScript can make it easier to use advanced with option B. It could also potentially make simple optimizations with closure better if it could communicate to closure which methods/variables are private. It could emit JSDoc comments to decorate fields with @private.

Currently the Google Closure compiler doesn't use these hints for anything useful, but providing that information for it doesn't hurt (since it removes comments) and it gives minifiers more information to optimize with.

antoinerousseau commented 9 years ago

If option A is fully efficient, I don't see why you would need B or C!

I would love to have option A's --minify-advanced!

mirhagk commented 9 years ago

I think the issue is that the compiler shouldn't necessarily be responsible for minification. I would much rather see all the information that TypeScript knows be emitted as jsdoc comments. That way JavaScript tools can utilize that information without needing to have a TypeScript parser.

ghost commented 9 years ago

Don't compilers generally have a switch to optimize for file size? Why not this one?

mirhagk commented 9 years ago

Compilers don't usually have a goal of near 1:1 mapping with source.

The point is that generating the resulting code is completely different with optimizing for file size (and other optimizations) than what it currently produces. I'd suggest a separate tool is created for an optimizing compiler (one that optimizes for either file size or performance), that makes use of the API tsc offers. I was planning on experimenting with the tsc compiler API so I may do an experiment in producing minified output.

ghost commented 9 years ago

The goal of the TypeScript compiler could be near 1:1 mapping of source unless the /min switch is set, in which case the goal would be to minimize it to the hilt without changing its exports.

mirhagk commented 9 years ago

Yes that's true, but then the back-ends are basically completely separate. I'd recommend implementing it as a separate module/project that uses the API, then if it does prove very useful it can be evaluated to be merged as part of the tsc command line.

joelgwebber commented 9 years ago

Meta: Is this the canonical issue tracking the proposal to create a path to an optimizing backend (be it built-in or via Closure annotations)? It appears to be at a glance, but if I'm missing a more appropriate spot, I'd appreciate a pointer to it.

I'd just like to throw in my 2¢ in support of an optimizing backend. My company's using Typescript very heavily, and while using Closure's basic optimization mode on the output helps to a certain extent, it's quite obvious that we can do a lot better. Code size may not matter to everyone, but it should -- it's not just about over-the-wire size, which is (mostly) mitigated by gzip, but about memory use, parse time, and runtime performance (yes, you can still achieve significant improvement through static optimization). There's a reason that Google invested heavily in optimization for both the Closure and GWT stacks (full disclosure -- I worked a lot on GWT and to a limited extent on Closure when I was there).

Just to be clear, this is what I mean when I suggest that we can do a lot better than just dropping whitespace and obfuscating local identifiers:

function rAb(a,b){if(!b.ib.a){Sae(a.a.a.a.a.d,(Klf(),new Nwf(b)));bOe(a.a.a.a.a.i,a.a.a.a.a.i.c)}}
function Cqb(a,b){a.f=b;if(!b.yb){a.a.we(new Aqb(a.b,a.f,null));return}wqb(a.d,b.Fb,new Iqb(a))}
function Bqb(a,b){var c;a.b=b;c=b.g;if(c.fh()){Cqb(a,b);return}vae(a.c,c.Br(0).Fb,false,new bbe(new Gqb(a)))}
function Pfd(a,b,c){var d;d=new Ufd(a);Bgd(a.a,d);Agd(a.a,b,c);dgd(a.b,new Wfd(a));Jpb(a.b,new Yfd(a));Qfd(a)}
function Ppd(a){var b;b=new qid(Dte(AFd(a.a)),bue(AFd(a.a)),aue(AFd(a.a)),Opd(a),knc(XEd(a.a)));return b}
function $pd(a){var b;b=new kmd(NXf(QFd(a.a)),(new rnd,KFd(a.a),new ndf),new hid(pKc($Ed(a.a))));return b}
function Rnd(a){var b;Sgf(a.s);if(a.o.S){return null}b=a.U.vg();return !!kfi(b).length&&!u_(b)?b:null}
function Pnd(a){Sgf(a.s);if(a.o.S){return nt(),mt}if(a.N.e.f.a){return nt(),mt}else{Sgf(a.M.e.f.a);return nt(),kt}}
function Gld(a){if(!a.j||!ZM(a.d.b,(Jw(),Qv))){return scf((Yci(),Yci(),Wci))}return icf(a.n,new Jld)}
function Mkd(a){a.a.wk((RJf(),KJf));wbb(a.a,eui);a.a.Oe(true);Fbb(a.a,new Ukd(a),BRf?BRf:(BRf=new wQf))}
function Jhd(a,b){var c,d;d=Bae(a.c,b);c=Lld(Ypd(a.a.a),b,d);return Nhd(new Ohd(a),(Ngf(c.d),new Ild(c,true)))}

The above is a random chunk of GWT output from a Google app. The details don't matter -- the point being that aggressive optimization can dramatically reduce output size, make a non-trivial difference in parse time and runtime performance, and even amplify gzip compression by allocating identifiers in such a way as to reduce input entropy.

As has been pointed out earlier on this thread, there are two obvious routes we can take:

I don't have a strong preference -- as long as it's possible to get good output, I don't care much how we get there. The output example above came from the GWT compiler, but Closure achieves similar results. Michael Bolin (who did a lot of the work on Closure at Google) created a proof-of-concept (http://bolinfest.com/typescript/) a couple of years ago, but didn't take it much further than that. It's not an entirely trivial exercise, because of the impedance mismatch between Typescript and Closure's inheritance mechanism in particular, but it doesn't seem like brain surgery either.

The hardest design problem, as I see it, is dealing with exposed vs. optimizable symbols. Closure has annotations for dealing with "exporting" symbols, and Typescript would need something similar to make the optimizer useful. There are also important edge cases like dealing with externally defined objects (both importing third-party libraries, and dealing with the output of APIs like JSON.parse). The compiler must know about these things if it is to avoid breaking the output with an aggressive optimizer.

I think it would be fairly easy to rally a few people to work on an optimizing backend for Typescript, but only if the team is bought into the idea. Trying to bolt such a thing onto the existing compiler, without the ability to tweak the compiler and language a bit, is probably a fool's errand. So I'd greatly appreciate any indication from the team as to their disposition on the subject.

NoelAbrahams commented 9 years ago

I really like the "random chunk of GWT output from a Google app". In addition to the benefits mentioned above, another objective is protection of intellectual property through obfuscation. If anybody has tried stepping through the code in Google Maps then they will know the protection that aggressive minification can provide in this regard.

The annotation (for excluding minificaton) is not only relevant for externally defined objects, but also relevant when properties of JavaScript objects are bound to elements in the HTML.

joelgwebber commented 9 years ago

I decided not to say anything about obfuscation for the purpose of, well... "obfuscation", at least partially because I know that tends to raise a lot of hackles in the web world :) A bit more seriously, I'm less concerned about it simply because I've spent so much time reverse-engineering highly-obfuscated Javascript (e.g., http://www.j15r.com/blog/2005/02/09/Mapping_Google) that obfuscation only feels like a speed bump. But hey, a big speed bump can still be useful.

Regarding annotation, right -- I forgot to mention that runtime-provided types are equivalent to external code. The (small, but important) distinction being that you tend to have relatively stable and available IDL for the former, whereas the latter's a bit of the wild west. If you have type information (e.g., via DefinitelyTyped), you're good to go, but if not you have a problem. Personally, I'd be fine with requiring explicit type information for all external libraries as a precondition for aggressive optimization, but I'm not sure that's a majority opinion.

FWIW, Closure basically takes that approach. If you don't have type annotations for external code, Turing only knows what it will do under advanced optimization (actually, I don't even think Turing knows, because it's probably undecidable, and the compiler certainly can't tell you). With GWT it was a bit easier, because you needed explicit (lightweight, optimized away) Java interface wrappers to call into Javascript in the first place. So the compiler only has an aggressive mode, because it can prove that the output won't be broken (as long as your Javascript methods don't "cheat").

Requiring explicit types also works for dealing with parsed JSON (our rather large body of Typescript uses interfaces for all parsed values; otherwise we'd be breaking things left and right). I believe Closure allows for this, but the traditional method was to require string accessor syntax for any properties that weren't defined by the compiler (e.g., value = parsedThing["someField"]). This is a pretty foul hack that I believe goes unchecked by the compiler, though, and I wouldn't be in favor of doing anything that nasty in Typescript. After all, that's one of the great benefits of making interface definitions an order-of-magnitude less verbose than in Closure.

ghost commented 9 years ago

@joelgwebber that is a really great appeal.

Just wondering: with variables and modules/classes and their members being necessarily declared, can't the optimizer ONLY rename members which are traceable back to a declaration? An any or an any which is known to implement an interface is still external code and those identifiers are not declared. (And declare declarations don't count.)

But in code with multiple namespaces, we would be forced to export too many items - items which are needed within the application by different namespaces, but not outside of it. So there'd need to be some additional level of accessibility between non-export and export, like internal?

fletchsod-developer commented 9 years ago

Don't forget there should be available an option in Visual Studio --> Config Transform (transformation) for Web.Config that are tied in to Visual Studio's Configuration Manager. That way we as developers should not be seeing minified javascript during development, especially when there's error or when debugging javascript source code.

I know this is about TypeScript minification thing but when in Visual Studio runtime via F5 key, it compile TypeScript to Javascript & I wouldn't want to see minified Javascript code during developing. Also, the Config Transform are tied in to publisher too. I would rather have minified javascript code when publishing to production sever but not minified to developer server.

Just saying.

joelgwebber commented 9 years ago

@Gitgiddy : I believe that's correct. The compiler can't go renaming symbols whose provenance are not known, and which it can't prove haven't "escaped" into any references or external code. In a language like Typescript, this requires global type inference. I know the compiler does a certain amount of type inference already, but I don't know how broadly scoped it is -- if it's just for locals, that could prove problematic.

@fletchsod-developer: Of course. We'd be nuts to run an optimizing backend with global type inference on every compile. You really only want that before deploying to production.

bryanerayner commented 9 years ago

I really would love to see this issue moved forward. It's evident that this is something people want (few users of Typescript would object, I'd challenge anyone to find a die hard objector). The issue is, it needs to be implemented correctly.

@Gitgiddy, I think you're absolutely right about the need to declare modules as internal vs external. But to add a keyword to the language for the sole purpose of minification isn't compelling. Private, protected, public - all of these keywords are very helpful to us for purposes other than minification, though they're incredibly helpful for that purpose.

With the merger of Typescript and AtScript, we finally have a syntax that's endorsed for data annotations. Is there a roadmap for specifying which annotations can be picked up by the compiler, I wonder? I'm sure that's something that's wanted by many people, so I'll assume that's avenue to pursue on a configuration level.

What if we were to steer this thread to a conversation about some standards which could be implanted, should minification be a feature of the compiler?

To start -

Solving these questions would be a good start. I feel that there could be more taken though:

Don't get distracted by the last point there. Let's start with the first three? I feel like there could be some progress on something if a common consensus began to emerge.

ghost commented 9 years ago

Perhaps with Ron Logan's (aka ronlo http://ajaxmin.codeplex.com/team/view) expertise, the development of this feature can elevate? He has done tremendous work in JavaScript minification over the past several years.

Ciantic commented 9 years ago

I think main selling point for dead code elimination is util libraries like lodash/underscore. TypeScript would become immediately much better for compiling those, than e.g. modularity of lodash which requires programmer to keep the mini-packages updated.

jimbarrett33 commented 9 years ago

I think this is a must have for TypeScript. It's a great language and gaining a lot of support, especially with the Angular 2.0 stuff. Now that I have developed a lot of TypeScript code and almost ready to deploy I now wish I hadn't used such long and descriptive naming (which I always do). Unfortunately, I thought they would minify OK. I tried using Closure but it broke more than it helped.

Coming from C# background I think annotations are the way to go. But they should be "opt out" instead of "opt in" for class properties and methods (both private and public), therefore they are minified by default.

Is there a way to elevate this so that someone on the TS team can at least tell us if it is being considered in the near future?

Until then I'm going to try to roll something on my own (which will probably leave me bruised).

mhegazy commented 9 years ago

Is there a way to elevate this so that someone on the TS team can at least tell us if it is being considered in the near future?

Minification has always been one of our most requested features, and one that we have talked about on and off throughout the past few years. It is a substantial amount of work though, assuming you are not just looking for white space removal, and variable name shortening. Moreover, minification has existed in JavaScript tooling for a long time, and there are already multiple minifiers that plug into existing JS workflows. We have been really busy with ES6 and other language/tooling features for TypeScript which made us shy from taking on such a big problem; specially that TypeScript compiles to JavaScript which allows you to leverage any existing JS tools out there. That said, it is not that we are ignoring the issue; it is still open because we believe that there is problem out there that TypeScript can help solve.

jimbarrett33 commented 9 years ago

@mhegazy, thanks a lot for the reply. I'm sure you're very busy and I wasn't trying to push! I just wanted to know if anything was on the near term radar. Good luck with the ES6 stuff. TypeScript is great.

NoelAbrahams commented 9 years ago

I second @jasonwilliams200OK's suggestion regarding Ron Logan. They have a well-maintained minifier (that I have used in the past) that could possibly be adapted to work for TypeScript. I have found Ron very proactive on the subject.

mhegazy commented 9 years ago

We are currently doing some JSDoc infrastructure work including parsing and AST representation, once that is done, generating type-annotated JSDoc comments should be fairly easy and will unblock more minification/optimization scenarios. We would be open to taking a PR for that.

raphaelfeng commented 9 years ago

Would like to see TypeScript compiler to support advanced minification feature!

So far, I have to create the externs file by myself and use the bracket notion to export the symbols.

For now, I am trying to generate the extern files from the .d.ts type file (aforementioned as Option B by @NoelAbrahams) by using typescript compiler APIs, so I don't need to manually change the externs file every time I use a new external API.

antoinerousseau commented 9 years ago

Why has this issue been closed?

ghost commented 9 years ago

@antoinerousseau, this issue is not closed :question::grey_exclamation:

antoinerousseau commented 9 years ago

oops yes sorry I got confused with the Closed label next to the #3503 reference just above

bryanrideshark commented 8 years ago

@mhegazy, you mentioned that it would be difficult to do, assuming that you weren't just looking for white space removal, and variable name shortening.

In my opinion, it is the second item in your list which would be the most beneficial. In our pipeline, we use UglifyJS to handle minification of TypeScript output, and it handles the AST optimization pretty well. What it can't handle, that Typescript can handle, is the second item you listed as a simpler task (variable name shortening.)

How could someone get more involved in that area of the project? Introducing variable name shortening as an option, would in my opinion be a huge piece of the pie, as that's the area where type definitions are required the most.

mhegazy commented 8 years ago

@bryanerayner we are currently looking into updating the implementation the emitter to allow for a transformation pipeline. no ETA at the point, but when this happens emitter changes should be much simpler to do.

I worry that a set of options to partially minify will not solve the original issue, but will introduce new complexities for users and in the code base. if this is something that you find interesting, feel free to look at the compiler sources and the API, and provide a proposal for how you intend it to work.

ghost commented 8 years ago

@mhegazy, so theoretically speaking, given the compiler is now exposed for third-party/external extensibilities, we can get a hook into AST and then implement the ultimate minification possible with all the trans-compilation context info. In this case, minification should be a feature of tsc, so consumers of TS should not rely on the external module (uglifyjs etc.).

mhegazy commented 8 years ago

@jasonwilliams200OK i agree. i believe the request here is for tsc to subsume your minifier in the tool chain. i do not think you would want to run tsc --minify then run your minifier again.

electricessence commented 8 years ago

++

hcapp01 commented 8 years ago

I do not understand why those things in ts 1.7 roadmap can be more important than minify. I had no choice but shipped my code with full function names. I am feeling myself as unprofessional as selling apples with apple tree attached, selling house without scaffold staging removed, taking my girlfriend to motel with her mom in the trip.

ghost commented 8 years ago

I do not understand why those things in ts 1.7 roadmap can be more important than minify.

Whaaaat? "Colorization of JSX code in VS 2015" (https://github.com/Microsoft/TypeScript/issues/4835) is NOT important than minification? :stuck_out_tongue_winking_eye:

Agree minification deserves some love. Not only shortening of names and elimination of whitespace but also some deep optimizations, joining of scattered file content etc. too. But naturally this is a complicated task which can be carried out in phases; basic->advanced.

kitsonk commented 8 years ago

Because TypeScript emits idiomatic, valid JavaScript, I suspect it isn't a priority because there are plenty of other tooling out there that does better than likely what the TypeScript can hope to achieve in the short term. Honestly folks, if you depend on TypeScript for you minification, you are likely not going to do an effective job of it. There is the Closure Compiler and UglifyJS. You can have those today, actually you could have had them before TypeScript.

NoelAbrahams commented 8 years ago

@kitsonk, there are some problems with using closure and uglify that have been discussed above.

electricessence commented 8 years ago

Maybe I'm missing something, but I've been having significant difficulty in getting sourcemaps and uglify/minify to work as expected. What I really want is a TSC.exe compiler option to minify the file with sourcemaps. IMO, simply stated, if you are using AMD or any other module based code, you really don't care about how the resultant JS looks because you have the sourcemaps.

Here's what I've found (spend hours and hours on this): 1) tsc with sourcemaps works perfectly without minification/uglify. 2) gulp-typescript + gulp-sourcemaps generates different sourcemaps than 1) 3) Any attempt at rendering minified files externally using gulp-sourcemaps, say in a 'min' folder creates strange references that don't resolve without overriding the sourceRoot with a function.

Ultimately, the above basically says there are bugs in the gulp plugins, but I would be happy if simply my resultant JS files were minified straight out of the TypeScript compiler.

electricessence commented 8 years ago

Also, it would be neat if you could replace the __extends code with an AMD module called 'extends' or something. :) Could take a chunk out of the total code.

ToddThomson commented 8 years ago

@mhegazy Is there any way with 1.7 to control or get access to the text writer or emitter? I just want to do a bit of experimenting with whitespace removal and private identifier mangling.