Scope hoisting renaming after babel transforms#2292
Conversation
| module.exports = { | ||
| Program: { | ||
| enter(path, asset) { | ||
| path.scope.crawl(); |
There was a problem hiding this comment.
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.
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.
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 forhof preact, hyperapp). (closes Tree shaking and React #1699, closes Scope hoisting/tree shaking bug (--experimental-scope-hoisting) #2084)babel-plugin-lodashtransforms 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: