-
Notifications
You must be signed in to change notification settings - Fork 4.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
Framework: Add package: @wordpress/babel-plugin-import-jsx-pragma #7493
Conversation
The test failure surfaces an interesting problem, which is that in order to build packages, we now need this packaged Babel plugin (chicken and egg problem). We could either (a) publish the package once manually, then reference the published version or (b) update the build process for packages to first build the required |
Option "B" seems like the better one to me. |
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 this is nice and I just have some thoughts on the docs.
It's assumed that you're also using [@babel/transform-react-jsx](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx/). | ||
Otherwise, you may encounter errors when encountering JSX tokens. | ||
|
||
``` |
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.
You should mark this as js
so it'll syntax-highlight nicely on GitHub, eg:
```js // .babelrc.js module.exports = { plugins: [ '@wordpress/babel-plugin-import-jsx-pragma', '@babel/transform-react-jsx', ], }; ```
Refer to the [Babel Plugins documentation](http://babeljs.io/docs/en/plugins) | ||
if you don't yet have experience working with Babel plugins. | ||
|
||
Include `@wordpress/babel-plugin-import-jsx-pragma` as a plugin in your Babel |
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 could be reworded to be instructive and less vague, as for any standard setup there'll be errors, and if the setup is non-standard we can assume developer familiarity. How about just:
Include `@wordpress/babel-plugin-import-jsx-pragma` (and [@babel/transform-react-jsx](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx/)) as plugins in your Babel configuration.
If you don't include both you will get errors with encountering JSX tokens.
|
||
## Options | ||
|
||
As the `@babel/transform-react-jsx` plugin offers options to customize the |
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.
Do we usually newline our markdown? If you don't it's nicer to diff/edit, I think doing this is annoying when making changes.
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.
Do we usually newline our markdown? If you don't it's nicer to diff/edit, I think doing this is annoying when making changes.
We have at some points. This is my first go at it. In retrospect, I agree that I don't like it, and we should probably discourage it. Updated in aad1bed.
const { scopeVariable, isDefault } = getOptions( state.opts ); | ||
|
||
// The module source isn't verified, since if at least the | ||
// required variable is within scope, its assumed to be |
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.
its -> it's
|
||
const { scopeVariable, isDefault } = getOptions( state.opts ); | ||
|
||
// The module source isn't verified, since if at least the |
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 I get this comment but it's a bit hard to parse, especially because "since" could be "because" to make it read more logically.
I don't have ideas for copyediting right now but could this be explained another way? Or maybe broken up into a few sentences so it's easier to parse?
// required variable is within scope, its assumed to be | ||
// compatible with the targeted transform, and otherwise would | ||
// conflict as a duplicate import if introduced separately. | ||
|
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 newline is weird to me.
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 newline is weird to me.
For context, there was previously a condition here which checked that the import source matched what we were expecting, but specifically I ran into issues with @wordpress/element
where we import createElement
from React proper:
gutenberg/packages/element/src/index.js
Lines 4 to 15 in 04c0ea2
import { | |
createElement, | |
createContext, | |
createRef, | |
forwardRef, | |
Component, | |
cloneElement, | |
Children, | |
Fragment, | |
isValidElement, | |
StrictMode, | |
} from 'react'; |
I will update the comment and shift it down a line to describe the behavior as part of what it is we're actually testing now.
Thanks for the review @tofumatt . I've pushed a few updates, including one to prebuild the |
source: '@wordpress/element', | ||
isDefault: false, | ||
} ] ); | ||
} |
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.
Do you think we should include this in the babel preset package?
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.
Yes 😄 It's been an awkward struggle thus far with the preset. I imagine it will be made easier once it's part of Gutenberg proper.
@@ -19,6 +19,14 @@ const plugins = map( babelDefaultConfig.plugins, ( plugin ) => { | |||
return plugin; | |||
} ); | |||
|
|||
if ( process.env.TRANSFORM_JSX_PRAGMA ) { |
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.
Also not sure why we need all these env variables (this one and the include/exclude ones)
Can't we just always use this plugin? What's the issue if always include it?
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.
See #7493 (comment)
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 see so I guess this would solve the issue right? #7556
return { | ||
visitor: { | ||
JSXElement() { | ||
hasJSX = true; |
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 read somewhere in babel docs that it's not great to rely on state variables like that and that it's probably better to rely on the "state" object passed to the visitors because of the way these visitors can be called in random orders.
I'm not a babel-plugin developer so I can't argue if it's legit here or not, just wanted to mention it.
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.
Based on the handbook description of visiting behavior, and particularly with its evaluation on the Program.exit
pass, I don't know that it should be a concern.
That said, I'll take a look to see if it's easy enough to switch to using state.
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.
Updated in 67653d0. Makes things simpler overall 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.
LGTM globally, the issue I have is these global variables, it makes it hard to follow. When should I use these globals and when not. I think it's better if it's handled automatically somehow.
Which globals are you referring to? The ultimate goal is that we don't rely on any globals. JSX is more of a special case in that it's technically magic that it's importing the |
Sorry I meant the environment variables |
I don't know that we should need to use the environment variables for any other package. It's more exclusively affecting Babel plugins where we expect to use the (built) plugin in the building of other packages. The other option is to rewrite the plugin so it doesn't require a build step (ES5). |
Ok I see, I think I'm fine with what we have. We can see if it's a lot of struggle over time and if we'd have to differentiate between "node/babel packages" and browser ones. |
Fixes #6956
Related: #742 (specifically #742 (comment) )
This pull request seeks to introduce a new package,
@wordpress/babel-plugin-import-jsx-pragma
, which seeks to serve as a compromise between competing objectives of developer experience (not needing explicit import to use JSX) and eliminating reliance on globals (previously the pragma was configured to awp.element.createElement
global). The transform effectively guarantees that the required import is made to be in scope wherever JSX is used, and updates our configuredpragma
fromwp.element.createElement
to simplycreateElement
.See included README.md
See demonstration
It resolves #6956 where end-to-end tests fail due to a conflict between the change detection tests reloading the page and core logic to unset the
window.wp
global on page unload, where previously failures could occur when a render happened after the unsetting (as it would attempt to unsuccessfully call the missingwp.element.createElement
).Testing instructions:
Verify that the editor loads without issue.
Ensure unit tests pass.