Skip to content
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

"error.stack;" expression removed by tree-shaker, breaks bindings #3974

Closed
mildsunrise opened this issue Feb 25, 2021 · 8 comments
Closed

"error.stack;" expression removed by tree-shaker, breaks bindings #3974

mildsunrise opened this issue Feb 25, 2021 · 8 comments

Comments

@mildsunrise
Copy link

  • Rollup Version: 2.39.1
  • Operating System (or Browser): Node
  • Node Version (if applicable):
  • Link to reproduction

Expected Behavior

The dummy.stack; line is not removed.

Actual Behavior

The dummy.stack; line is removed.

Accessing stack is necessary for the prepareStackTrace function to be called. Removing it breaks the bindings package. (I'm not sure that the tree-shaker can be smart enough to detect the side-effect here, but the documentation asked to file an issue, and I didn't find an existing one, so I did)

@kzc
Copy link
Contributor

kzc commented Feb 25, 2021

Odd API. Who knew?

I guess all stack property reads have to be registered as having side effects.

@kzc
Copy link
Contributor

kzc commented Feb 25, 2021

This is notable:

https://v8.dev/docs/stack-trace-api#compatibility

Compatibility

The API described here is specific to V8 and is not supported by any other JavaScript implementations. Most implementations do provide an error.stack property but the format of the stack trace is likely to be different from the format described here.

@mildsunrise
Copy link
Author

yes, everything regarding stack traces is probably implementation dependent... if you think this is out of scope feel free to close, I just wanted to let you know

@mildsunrise
Copy link
Author

for context: even if implementation dependent, this API seems to be important in the ecosystem; so much that we explicitly preserved its behavior when source maps are present (nodejs/node#31143)

@kzc
Copy link
Contributor

kzc commented Feb 26, 2021

It's not my call, but I'm not against supporting this if it's widely used - even though property reads with side effects are an anti-pattern. It would be relatively easy to add a side effect for all stack property reads. It would be more difficult to isolate error related stack property reads in all situations.

@kzc
Copy link
Contributor

kzc commented Feb 26, 2021

This patch retains all stack property accesses:

--- a/src/ast/nodes/MemberExpression.ts
+++ b/src/ast/nodes/MemberExpression.ts
@@ -71,4 +71,15 @@ function getStringFromPath(path: PathWithPositions): string {
 }
 
+// properties with read side effects - just one entry for now
+const propertyEffects = {
+       __proto__: null,
+       stack: true
+};
+
+function propertyReadHasEffects(property: any) {
+       return (property.type == 'Literal' && property.value in propertyEffects) ||
+               (property.type == 'Identifier' && property.name in propertyEffects);
+}
+
 export default class MemberExpression extends NodeBase implements DeoptimizableEntity {
        computed!: boolean;
@@ -174,4 +185,5 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE
        hasEffects(context: HasEffectsContext): boolean {
                return (
+                       propertyReadHasEffects(this.property) ||
                        this.property.hasEffects(context) ||
                        this.object.hasEffects(context) ||

With patch:

$ echo 'var o={}; o.foo; o["bar"]; o.stack;' | rollup --silent
var o={}; o.stack;
$ echo 'var o={}; o.foo; o["bar"]; o["stack"];' | rollup --silent
var o={}; o["stack"];

@kzc
Copy link
Contributor

kzc commented Mar 9, 2021

--treeshake.propertyReadSideEffects=always can now be used as a workaround for tree shaking with getters with side effects.

@mildsunrise
Copy link
Author

sorry about not replying, and thank you for patching this 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants