With https://github.com/Microsoft/TypeScript/pull/16631 (the PR to solve https://github.com/Microsoft/TypeScript/issues/13721), TypeScript now emits a
/** @class */
comment when downleveling classes. Our hope is that Uglify can understand the intent and provide some mechanism to remove unreferenced downleveled classes.
Currently the work is in our RC branch, but depending on when other tools could actually understand these changes, we might postpone to our 2.6 release instead.
CC @TheLarkInn @IgorMinar @chuckjaz @alexeagle @mhegazy
Hey Uglify team @kzc et al. Thanks for the continuing support and hard work y'all have been doing with uglifyes. If you are all green light on this feature we'd (webpack) be happy to help in anyway for the implementation of this if needed.
Otherwise keep up the awesome work. 馃憦馃憦馃憦
No uglify change is required. It's trivial for the user to replace /** @class */ with /*@__PURE__*/ with a regex. Likewise for Rollup and Webpack with a plugin.
Would you accept a PR to create a feature which sets an "alternate" label to /@__PURE__/?
options: {
pureLabel: /** @class */
}
This way tooling that need a bit more flexibility could do so from uglify, etc. And technically if we needed to we could write a webpack-loader, if last resort. I think from this stance the TS folks want to have an awesome win OOB.
Thoughts? Either way we can run with both options. Thanks for the quick response.
/*@__PURE__*/ annotations are already in use in the wild. I don't see the need for alternate pure annotation names.
uglifyjs-webpack-plugin would be the logical place for the /** @class */ to /*@__PURE__*/ annotation replacement logic. By the same token, the Typescript compiler's annotation could be configurable.
We originally considered use of "@__PURE__", the issue is that it is missleading since the compiler can in no way attest that the class definition is pure (when decorators and static intializers are involved). It is particularly confusing since the term "pure" when used with functions in compilers/minifiers already had a well defined meaning.
"@class" on the other hand is more declarative and makes the handofff from the transpiler to the minifier simpler, it basically notes that the code originated in an ES6 class, and lets the minifier decide what to do with it.
There is also prior art for "@class" in the jsdoc releam.
I understand that uglify already has an annotation in place with "__@PURE__", and we are not suggesting this support be removed; we would recommend adding "@class" as an alternative. We also would be happy to help if you are accepting PRs for this proposal.
We originally considered use of "@PURE", the issue is that it is missleading since the compiler can in no way attest that the class definition is pure (when decorators and static intializers are involved).
@mhegazy You're missing the point. It is not misleading nor is it relevant if the function call is actually pure. When the user marks a function call with a pure annotation they are instructing uglify to treat it as if it is pure for the purposes of code removal when its return value is unused and the programmer has decided that any potential side effects are not significant to program execution. Uglify has been using this terminology for pure_funcs functionality without issue for years. For example, some uglify users list the babel-generated _classCallCheck as being pure with pure_funcs so those calls can be dropped from ES5 generated code.
Just curious... will the typescript compiler generate /** @enum */ annotated ES5 IIFEs for emums or use /** @class */?
The expectation here is that the TypeScript compiler would emit @__PURE__ on the emitted code, egardless of who is going to use it, it reads "pure"; and pure functions are a well established concept. The output is not only consumed by uglify, it can be used by closure, rollup, etc; it can also be inspected by humans and we would like the output to be accurate. It would have been different if the commment had "uglifyjs:pure" but it does not. We found it misleading for the compiler to emit a comment that it knows to be inaccurate.
For enums, TS already has a concept of const enums, that are erased from the output, so this is not relevant here. Namespaces with no statements might be, but we rather stick to standard ES concepts in inter tool communication.
The output is not only consumed by uglify, it can be used by closure, rollup, etc
Both webpack and rollup have string replace plugins that can change the typescript generated annotation to a form that uglify can process. No code changes required.
@kzc good to close?
yep