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
Unused constructor call is unsafely stripped out #1771
Comments
Polyfill detection code and polyfills shouldn't be run through Rollup. It should be prepended to the bundle or loaded separately. Such feature detection is at odds with the goals of Rollup - it assumes an ES6 environment and that You could hack out those classes, but that's not a great idea: --- a/src/ast/nodes/shared/pureFunctions.js
+++ b/src/ast/nodes/shared/pureFunctions.js
@@ -22,7 +22,6 @@ simdTypes.forEach( t => {
'Date', 'Date.UTC', 'Date.now', 'Date.parse',
'String', 'String.fromCharCode', 'String.fromCodePoint', 'String.raw',
'RegExp',
- 'Map', 'Set', 'WeakMap', 'WeakSet',
'ArrayBuffer', 'ArrayBuffer.isView',
'DataView',
'JSON.parse', 'JSON.stringify', If you must run such code through Rollup, I'd suggest calling a bogus function with function detect(x) {
if (x === detect) throw detect;
return x;
}
var hasBadPolyfill = false;
try {
var nonExtensibleObject = Object.preventExtensions({});
detect(new Map([[nonExtensibleObject, null]]));
detect(new Set([nonExtensibleObject]));
} catch (err) {
//console.log("caught:", err);
hasBadPolyfill = true;
}
console.log(hasBadPolyfill); |
H @gaearon , I must admit, though, that feature detection is something I did not have on my radar as much as I should have. For the short term, I would actually suggest to do what @kzc mentions but is not happy about–to remove the functions in question from the "pure functions" list. This is not unprecedented:
I am very open to feedback and further suggestions regarding this. If we go with option 3, which I very much recommend, we should also
What do you think? |
To be 100% clear, in my case I'm not adding a polyfill. I am trying to detect a bad polyfill from my library (by feature testing) so I can avoid using it. I don't think it's practical for us to separate this code from Rollup. I don't see a non-convoluted way to do this while keeping the source modular. An annotation to prevent stripping out seemingly pure expressions would indeed be helpful. |
This may be pedantic, but I wouldn't label this a bug - Rollup is working as designed. This is a feature request. When the code in the top post is run through Google Closure in advanced mode it produces: var a = !1;
try {
Object.preventExtensions({});
} catch (b) {
a = !0;
}
console.log(a); Perhaps Closure has some similar annotation to prevent side-effect-free code from being dropped. |
Fair enough :-) I agree it's a feature request from the context above. |
A zero overhead production workaround with existing tools: $ cat keep.js
var hasBadPolyfill = false;
try {
var nonExtensibleObject = Object.preventExtensions({});
keep(new Map([[nonExtensibleObject, null]]));
keep(new Set([nonExtensibleObject]));
} catch (err) {
hasBadPolyfill = true;
}
console.log(hasBadPolyfill);
$ rollup keep.js -f es --silent | uglifyjs --toplevel -mc pure_funcs=[keep],passes=3 -b
var e = !1;
try {
var n = Object.preventExtensions({});
new Map([ [ n, null ] ]), new Set([ n ]);
} catch (n) {
e = !0;
}
console.log(e); In dev mode the calls to Object(new Map([[nonExtensibleObject, null]]));
Object(new Set([nonExtensibleObject])); which is retained by both uglify and Closure (in simple mode). Edit: Or just have rollup remove |
I guess I have to agree this is currently an enhancement. I thought that this might be a potentially more wide-spread issue that had just gone under the radar but browsing through core-js I think they are–for the time being–still safe from being broken by our algorithm. As for GCC, it seems that even though they too encountered these issues, no annotation syntax was introduced. Uglify does not seem to have a syntax for this as well so if we introduce this, this might actually be a first. As for myself, I would very much like to introduce such a syntax now because
I would suggest introducing an annotation that can be placed in front of any statement and that will prevent this statement AND ALL ITS CHILDREN from being removed (that way, people will not need to know too much about AST semantics). As for a name, |
Perhaps we could apply a heuristic here and detect if a side-effect-free statement that also has the chance of not being supported in legacy browsers, that is also within a try-catch block indicates a "feature detection" and that it shouldn't be treeshaken. |
(personally I'd prefer to avoid annotations wherever we can help it as a guiding philosophy of a "do-the-right-thing js compiler") |
I am not a huge fan of heuristics that
I.e. why is it "the right thing" to keep side-effect free (by spec) statements in try...catch blocks? What about side-effect-free statements in functions that are called from within try...catch blocks, do we need to trace this "being called from a try-catch blocked"? What if I want to do it in a Promise instead? Which statements do I want to keep? Do we want to maintain a second list of pure functions that "are impure when used inside a try-catch block"? Annotations are the cleanest approach that even works when re-bundling bundled code. |
Why even warn about bad polyfills? Most users use |
Because if you do get a bad one you're gonna blame React for being slow. |
@gaearon Why not recommend a specific polyfill in the README? |
I ran into this issue recently when using @babel/preset-env's |
rollup treeshaking is removing the Object.getOwnPropertyNames FAILS_ON_PRIMITIVES feature test. This is related to these rollup issue rollup/rollup#1771 rollup/rollup#2790 Related issue and fix zloirock#513 zloirock@f813c4e
rollup treeshaking is removing the Object.getOwnPropertyNames FAILS_ON_PRIMITIVES feature test. This is related to these rollup issue rollup/rollup#1771 rollup/rollup#2790 Related issues zloirock#494 zloirock#513
I know there has been a long silence around this issue but #2892 will finally provide a solution for this that should work for you, comments welcome. |
Citing myself:
I am growing older and starting to accept things. |
This commit ensures that Storybook, Jest and a preact project render the components/contents correctly. Previously a variety of mistakes were made that now are rectified: * Jest does not honour .babelrc, so we gave up on JSX and pragma niceties * Previous tests were not actually rendering the component from the bundle * package.json specified an incorrect bundle entry * dist/ folder was made part of version control * Hidayah implementation was leveraging react-markdown to render the contents. While this works for storybook, bundling this code implied that react-markdown tries to mutate the content that Rollup marks as immutable: rollup/rollup#1771 In addition to the above: * Abstract out the implementation of markdown_plugin so Rollup and Vite can reuse.
This commit ensures that Storybook, Jest and a preact project render the components/contents correctly. Previously a variety of mistakes were made that now are rectified: * Jest does not honour .babelrc, so we gave up on JSX and pragma niceties * Previous tests were not actually rendering the component from the bundle * package.json specified an incorrect bundle entry * dist/ folder was made part of version control * Hidayah implementation was leveraging react-markdown to render the contents. While this works for storybook, bundling this code implied that react-markdown tries to mutate the content that Rollup marks as immutable: rollup/rollup#1771 In addition to the above: * Abstract out the implementation of markdown_plugin so Rollup and Vite can reuse.
This commit ensures that Storybook, Jest and a preact project render the components/contents correctly. Previously a variety of mistakes were made that now are rectified: * Jest does not honour .babelrc, so we gave up on JSX and pragma niceties * Previous tests were not actually rendering the component from the bundle * package.json specified an incorrect bundle entry * dist/ folder was made part of version control * Hidayah implementation was leveraging react-markdown to render the contents. While this works for storybook, bundling this code implied that react-markdown tries to mutate the content that Rollup marks as immutable: rollup/rollup#1771 In addition to the above: * Abstract out the implementation of markdown_plugin so Rollup and Vite can reuse.
Example here:
Result:
However this breaks the feature detection we were trying to do.
(In our case, this led to a crash: facebook/react#11745.)
The text was updated successfully, but these errors were encountered: