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
rollup removes feature detect code from inside function when it should not: broken functionality in generated output #2181
Comments
Silly me. Forgot to mention:
|
I think it is actually the same situation as #1771. As stated there, I am rather opposed to implementing a heuristic to keep certain statements and would prefer an annotation solution. As you did not tell us about your background, would annotations be a suitable solution for your use case? |
Annotations as an alternative to heuristics is fine. Bottom line for me is the code doesn't get too cluttered, like it is now with smartypants JS expressions to misdirect rollup. 😉 The drawback of having to inject annotations is that one has to visit/find all the spots where rollup does the wrong thing, which means extra work on our own and third party libs and added risk where test coverage is not 100% cross-platform (this issue was detected via code review, but would otherwise need specific test platforms to trigger it, which isn't always happening), but from a rollup maintenance POV I can understand your preference for annotations. When we go and use annotations, do we have a Big Switch to turn rollup optimizations off?Alternatively, can rollup code reduction/tree shaking be disabled globally via its config? That would significantly help diagnosing issues which crop up due to this issue and #1771 as then we can more quickly reduce the search area while debugging/analyzing! (Same as when you've got trouble in production-stage code and kill the minifier phase to check if the problem is inside the minifier or elsewhere.) I looked at the rollup documentation but couldn't find such a configuration option. I wonder if I overlooked it? Thanks for the quick reply! 👍 |
My worry with annotations as a fix here is that it sets down a path where the expectation is that if code does something that "isn't sensible" (by whatever definition deemed by Rollup), then annotations are necessary to make it actually work. Us advanced users will be fine - but it leaves out the beginners who won't know why someone else's code broke their build, which won't be a great user experience. Perhaps it's time to introduce "optimization levels", where things that can possibly be unsafe can be disabled on the "safe optimization" setting? |
The switch exists, it is
A heuristic is much more unpredictable in its behaviour than an annotation so the result will be that the code will work for some out of shear luck but not for others who tried to be intelligent and wrote their feature detection the wrong way. As feature detection is a rather advanced topic anyway I would rather hope this is something to be implemented by plugin makers and not by average users. |
I guess we should document |
My mistake! 😊 (https://rollupjs.org/guide/en#big-list-of-options -> Danger Zone -> Tested it and disabling treeshaking all around works fine with
|
Closing this issue as now it's become a duplicate of #1771. |
AFAICT this is closely related to #1946 and #1771.
A stripped-down showcase + work-around is provided below. At the bottom is a suggestion how this might be approached more consistently and without the need to 'discover' this issue ad hoc by everyone anytime because tests start to fail or code inspection turns up 'weird chunks of code' or ... 😉
How to reproduce
Take the code below (which comes from the XRegExp library @ https://github.com/slevithan/xregexp/blob/master/src/xregexp.js#L60) and run it through rollup using the given config file and command line below:
(dummy.js 💥💥💥)
(rollup.config.js)
(command line)
Produces this FAULTY output:
(dist/xregexp-cjs.js 💥💥💥 )
As you can see, the
new RegExp(...)
statement inside the try/catch block has disappeared, which kills the intended functionality of the given function: feature detection of regex flags cross-platform.This looks a lot like #1946...
Work-around for today
The idea here is to make it hard for rollup to analyze the code while we still guarantee the proper function result when it executes.
That implies we'll need include the
new RegExp(...)
into the codeflow towards thereturn
-ed function result somehow; fortunately JavaScript doesn't care about variable type, hence we can construct an expression inside the try/catch which is not immediately obvious constant assuming an expression evaluator inside the rollup 'compiler' which does not does a full constant-folding and type propagation analysis.Lucky for us, rollup is not that smart yet.
WARNING: this trick may not work in future rollup versions when the code analysis gets smarter in there!
Here's the tweaked version which passes okay:
(dummy.js 👍 )
(command line)
now produces this CORRECT output:
(dist/xregexp-cjs.js 👌 )
Suggestion how rollup could handle this pattern 'better'
As a lot of feature testing and other non-obvious code with lots of side effects often is wrapped in a try/catch, I'ld suggest to simply kill tree-shaking/code-removal logic for any code chunks which reside inside a
try
section of a try/catch/finally block.If there's any 'magic' happening in the
catch
section, then (at least in our code bases) such 'magic stuff' is itself wrapped in another try/catch block, so the logic rollup might want to follow is then quite simple: no code removal inside any try/catch block.The suggestion covers only code directly inside the
try
section; any code that exists inside a try/catch indirectly, i.e. via one or more function invocation levels, is free-for-all AFAIAC; if such code chunks, sometimes observed in (unit/system) test rigs, should be subjected to the same 'no code cleanup in here' rule suggestion, I'd say wrap that chunk in another try/catch block like this:The text was updated successfully, but these errors were encountered: