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
Mark transpiled JSX elements as pure #11126
Conversation
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.
Looks good to me. Here a few minor things:
@@ -1,3 +1,4 @@ | |||
/*#__PURE__*/ | |||
React.createElement(Component, babelHelpers.extends({}, props, { |
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.
Maybe babelHelpers.extends
should get a pure annotation too?
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.
Maybe also other helpers are pure, I'll check 👍
/*#__PURE__*/ | ||
React.createElement(Composite, null, | ||
/*#__PURE__*/ | ||
React.createElement(Composite2, null)); |
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.
The output code would be a little bit more readable and less verbose if the comment would not be in a separate line but in the same line:
var x =
/*#__PURE__*/
React.createElement(Composite, null,
/*#__PURE__*/
React.createElement(Composite2, null));
vs
var x = /*#__PURE__*/ React.createElement(Composite, null, /*#__PURE__*/ React.createElement(Composite2, null));
But this isn't important...
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 agree, I'll do it in a separate PR since it isn't strictly related to adding the annotation to JSX elements.
I think it’s worth being careful about this. One could make a custom JSX pragma that is not pure and this would break that. Maybe only do it for the default React.createElement? Or have a whitelist (e.g. preact, etc.)? |
Yeah, I agree on @devongovett , I think we should limit pure annotation when We can offer limited whitelist and finally a |
6095d04
to
c864ef9
Compare
I don't think that we can have a whitelist, because the pragma isn't based on the imported module but on the variable name (for example, @developit When this PR is merged, Preact can benefit from these changes if the @JLHwung I didn't add the check for |
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 was wondering if it would make sense to only add annotations to elements in the top level scope, since they are the ones preventing tree-shaking. |
@nicolo-ribaudo Rollup can also shakes non top level functions, example is here. |
Yeah, I'm wondering how common it is to have unused elements inside functions. |
833c80e
to
af2761e
Compare
...ransform-function-name/test/fixtures/function-name/export-default-arrow-renaming-3/output.js
Outdated
Show resolved
Hide resolved
13e7237
to
b03ef6e
Compare
pure, | ||
throwIfNamespace = true, | ||
useSpread, | ||
runtime = "classic", |
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.
This is a breaking change from the "new JSX" PR, because that PR accepts runtime: false
as an alias for runtime: "classic"
while this one doesn't.
@lunaruan Do you think that this change is ok?
If this PR ends up being merged in a different release, I'll have to revert this line.
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.
Yeah, this should be okay. No preference for whether runtime: false
should alias to runtime: 'classic'
as long as runtime: 'classic'
is the default behavior
fc2e36a
to
2214736
Compare
I have finished adapting this PR after #11154 (I copied the same logic to the new transform) |
React.createElement
(and often also for other JSX implementation, but it's not guaranteed) calls are pure: they are meant to produce an object which then is used by the React (or other lib) runtime to actually instantiate the component.We can mark them as such to help minifiers strip unused JSX elements.
Adding it to every component might not seem ideal, but:
If some props aren't pure, minifiers won't remove them even if there is the annotation:
This PR solves #11037 in a different way than #11105, because we mark JSX elements as pure no matter if they are hoisted or not.
The output from that issue would now be
Which can be tree-shaken.