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

Wrap hoisted JSX elements into IIAFE so pure annotation can work #11105

Closed
wants to merge 2 commits into from

Conversation

JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Feb 6, 2020

Q                       A
Fixed Issues? Fixes #11037
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
License MIT

@babel/plugin-transform-react-constant-elements adds pure annotation to the hoisted JSX elements.

var _ref2 =
/*#__PURE__*/
<div>child</div>;

const AppItem = () => {
  return _ref2;
}

However, in reality it never work as expected with bundlers/minifiers because terser only supports pure annotation on call expression (terser/terser#513 (comment)). This PR wraps the hoisted elements into an IIAFE so Rollup can remove unused constant elements.

var _ref2 =
/*#__PURE__*/
(() => <div>child</div>)();

Note that this PR will cause unnecessary hoisting under certain scenarios, (see comments below). To mitigate this side effect we may have babel-traverse exposed the Path Hoister API, but it could not be done in v7 due to our semver requirement.

cc @babel/react

@JLHwung JLHwung added PR: Bug Fix 🐛 A type of pull request used for our changelog categories area: react labels Feb 6, 2020
{_ref3}
<AppItem />
</div>;
{_ref4}
Copy link
Contributor Author

@JLHwung JLHwung Feb 6, 2020

Choose a reason for hiding this comment

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

The <AppItem /> here is unnecessarily hoisted to the same scope of _ref because the Path Hoister can not neglect the introduced IIAFE. Note that when the JSX element is not hoisted to the top level, its children may still have opportunity hoisted to top level. But we can't know which scope the element will be hoisted to until we have run path.hoist(), after that the AST is changed and it's too later to determine whether such hoisting is favourable.

Copy link
Member

Choose a reason for hiding this comment

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

What if we added a new parameter to path.hoist(), to say "hoist this path but only if it can go at least up to this scope"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, we can do it but due to the semver requirements we can not ship it in patch/minor releases unless we are doing dirty version checks.

Do we have plans to change semver to minor-version compatibilities in Babel 8?

Copy link
Member

Choose a reason for hiding this comment

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

If someone uses an old @babel/traverse version, their JSX elements will be hoisted singularly because the "minimum scope" parameter is ignored. It's not optimal, but it will still perfectly work.

@gaearon
Copy link
Member

gaearon commented Feb 10, 2020

This seems like it adds overhead to the startup path, which is bad. However, the current transform is already non-ideal in that sense (it adds startup overhead with no lazyness). We couldn't get it working at FB so I don't think we care strongly about how it works.

@nicolo-ribaudo
Copy link
Member

Actually, adding a lazy option (similar to the commonjs plugin) seems a good idea to me.

@JLHwung
Copy link
Contributor Author

JLHwung commented Feb 11, 2020

Closing it in favor of #11126

@JLHwung JLHwung closed this Feb 11, 2020
@JLHwung JLHwung deleted the fix-11037 branch February 11, 2020 15:32
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 13, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: react outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

@babel/plugin-transform-react-constant-elements generates non-tree-shakeable output
3 participants