-
-
Notifications
You must be signed in to change notification settings - Fork 383
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
Don't leave comments with whitespace after removing annotations #526
Comments
That's pretty reasonable :) if you're willing to PR this, please do go ahead! Thanks in advance! |
Pure annotations were removed upon output on purpose. Comments can shift in a number of |
Here's another example of the difficulty of retaining pure annotations correctly - even when the annotations are used appropriately on calls: Given:
we'd expect the minified output to produce:
Now let's misspell the pure annotation to see what happens:
And if we convert
because pure annotations are greedy and choose the longest subsequent call (or There are many other different ways retaining pure annotations can go wrong if done incorrectly. |
I am finding that |
As @kzc pointed out: This is intentional as the annotations might be in the wrong place after minification. They‘re open for a PR but the solution is not as easy as just preserving them as one needs to make sure the annotations are at the right place after minification |
@sventschui I just find it bizarre that it renders terser --comments "/__PURE__/" |
That's very interesting. We can easily check if the comments are just whitespace after removing the annotation and remove them. Let's do that. |
@fabiosantoscode But I don't think that solves my problem of leaving |
Yeah, I think we don't want to do that. At first I thought why not, then I read @kzc's reasoning and further thought of the maintenance burden of trying to move code with these annotations and preserve the annotations. Plus, I've been thinking of a new way of annotating which is a lot more resilient. It involves an npm module with do-nothing functions that have special meaning to the compiler. This approach of using comments works great if the only compiler reading them is UglifyJS/Terser and they are removed before output. To achieve something that can be read by multiple compilers a more solid approach is required. |
We currently have Rollup, which we use for building the bundle, converts this: export foo = /*#__PURE__*/ bar({ some: content }) to this: var foo =
/*#__PURE__*/
bar({ some: content }) And we would like to preserve the PURE comment. Currently terser preserves the comment delimiters, but not the content of the comment: var foo=/* */Zx({ some: Ab }) |
I advised the individuals who implemented pure annotations in Rollup to achieve a high degree of compatibility with uglify and its forks. Rollup does not perform most of the optimizations that uglify-js and terser do, so it manages to avoid the problems associated with retaining pure annotations (as far as I know). Please take the time to read and understand the posts above detailing why pure annotations were intentionally removed by uglify-js and terser to avoid incorrect results. There are other issues that I haven't mentioned in this thread. Even if my example above #526 (comment) were to hypothetically emit the following correctly annotated output with added parentheses:
terser would continue to correctly process it:
however Babel with default settings would not retain the necessary parentheses due to this known issue:
so that when this Babel output would be (re)run through terser it would produce this undesirable result:
This is why uglify and its forks are as conservative as they are and elide pure annotations upon output. Workarounds can be devised for all of these issues, but they are not as trivial as they may appear. |
Closing this as fixed with #550 |
I have exactly the requirement that sventschui described. I understand the risk of leaving the "pure" comments, and I want to leave them despite the risk. Thank you for making this possible. A note for people from Google: besides adding a const terserConfig = {
module: true,
format: {
comments: /^\s*[#@]__PURE__\s*$/,
preserve_annotations: true,
},
} |
Over at preact we ship minified code but want the code to be tree-shakeable. While implementing this we faced some issues with inheritance. To solve this same issue babel, etc. construct classes/prototypes inside an IIFE that is marked as
/*#__PURE__*/
. We now want to do the same (see preactjs/preact#2156 (comment)) but face the issue of terser removing all annotations here:terser/lib/output.js
Line 658 in 6589965
I'd like to ask whether you'd be open to extend terser with a config option to preserve these annotation comments? I'd be happy to PR this change.
Another thing I asked myself is whether this might have side effects. When something is inlined it might be dangerous to keep the
__INLINE__
annotation. I'm not super deep into the magic of minification so you might be able to answer this question quicker/better than me.Bug report or Feature request?
Feature request
Version (complete output of
terser -V
or specific git commit)n/a
Complete CLI command or
minify()
options usedNote the new option
--keep-annotations
that might takeall
, a regex or a list of stringsterser --comments /__PURE__/ --keep-annotations all
terser
inputterser
output or errorExpected result
The text was updated successfully, but these errors were encountered: