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

fix(shaker): fix some edge cases related to specific export patterns #951

Merged
merged 1 commit into from Mar 26, 2022

Conversation

jpnelson
Copy link
Contributor

I've tried adopting the shaker method (over extraction) and ran into some edge cases – I've added tests that explain what those edge cases look like.

Motivation

There are three cases that weren't shaken correctly by the shaker algorithm:

  1. Assigning to an export (eg. var x = module.exports = {...})
  2. Exporting objects (with computed keys)
  3. Exporting objects directly (eg. module.exports = {...}) and using this object as a default import elsewhere

Summary

This fixes it by changing the shaker algorithm to support these cases.

I think so long as we can get these new tests to pass, I'd be happy to take suggestions on exactly how we can implement the fixes. In particular, the biggest change is to support assigning to an export, for example:

var x = module.exports = {...}

The issue there is that the variable declaration var x = ... is marked as not-alive, and so the whole expression is shaken. This fixes it by checking variable declarations, but we could also change the shake part of the code to check for alive children. I think that that may have broader implications though.

Very impressed with the shaker algorithm overall, thanks for writing it!

Test plan

Tested with snapshot tests. I believe for CI to pass, #950

@Anber Anber merged commit 18ca481 into callstack:master Mar 26, 2022
@Anber
Copy link
Collaborator

Anber commented Mar 26, 2022

Looks perfect! Thank you!

* The rest of the subexpressions can be omitted if they don't have dependent nodes.
* evaluates to the last subexpression in the list.
* In theory, some could be emitted, but we set all the subexpressions
* to have dependencies since there could be references in the list.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please provide an example when we need to keep the full list?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed CI was failing so I added that here: #953

an example is something like:

var n = 0;
export default number = (n = 5, n);

if we took only the last item in the sequence expression, we'd be left with

var n = 0;
export default n;

which isn't equivalent.

I created #953 which adds a proper test case for this, and I noticed CI was broken too. This updates that 🙏

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example should work properly without changing the shaker, because the last expression is marked as valuable by default and the first is marked as a dependency of the last one, so that both are stay alive.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see now why you changed that behaviour :)

	var object = (_object = {}, (0, _defineProperty2.default)(_object, computedKeyName, 'red'), (0, _defineProperty2.default)(_object, "blue", 'blue'), _object);

The problem here can be solved by keeping alive all members in sequence, but it isn't the best solution. I'll release the fix today.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see now why you changed that behaviour :)

	var object = (_object = {}, (0, _defineProperty2.default)(_object, computedKeyName, 'red'), (0, _defineProperty2.default)(_object, "blue", 'blue'), _object);

The problem here can be solved by keeping alive all members in sequence, but it isn't the best solution. I'll release the fix today.

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

Successfully merging this pull request may close these issues.

None yet

2 participants