-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Scope hoisting renaming after babel transforms #2292
Scope hoisting renaming after babel transforms #2292
Conversation
@@ -51,6 +51,8 @@ function hasSideEffects(asset, {sideEffects} = asset._package) { | |||
module.exports = { | |||
Program: { | |||
enter(path, asset) { | |||
path.scope.crawl(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get why we need this, isn't babel traverse going to .crawl
for us already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is an explanation: #1699 (comment)
It seems that when JSX is transformed (calling babel.transformFromAst(asset.ast, asset.contents, config)), the scope binding is not updated (only AST is updated). So in the hoist phase, we fail to find binding of React because there is still JSX syntax in the scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think babel doesn't recrawl the scope automatically, only when the scope is first initialized. That happens before lots of babel transforms run which can modify references, in this case the class transform. Then we get to our hoisting transform and we need to re-crawl to make sure we have updated references since babel traverse doesn't do that automatically.
↪️ Pull Request
With this change the renaming part of scope-hoisting seems to work with other babel-transforms as well. E.g.:
<span>Test</span>
gets transpiled toReact.createElement("span", null, "Test")
, but React isn't getting renamed (same forh
of preact, hyperapp). (closes Tree shaking and React #1699, closes Scope hoisting/tree shaking bug (--experimental-scope-hoisting) #2084)babel-plugin-lodash
transforms the ast just like jsx (closes babel lodash plugin and parcel tree shaking #1821)constantViolations undefined
: withstyled-jsx
- closes Experimental scope hoisting: Cannot read property 'constantViolations' of undefined #1538, withplugin-transform-runtime
- closes scope hoisting: Cannot read property 'constantViolations' of undefined #2255I've added test for jsx and superclasses to the scope-hoisting/es6 folder.
Is a reason for the custom renaming logic? All scope-hoisting tests still pass with simply
scope.rename(oldName, newName)
.💻 Examples
Previously, scope-hoisting didn't correctly rename the superclass identifier (same problem with jsx)
src:
Before hoisting:
After hoisting: