Element: Make the package importable in React 19 - #80053
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Good spotting, it's partially duplicate, I was hesitant on sending both versions in one commit, but yes, I'm going to remove the duplicate parts right now and just leave the compatibility layer for Updated 👌 |
c1df306 to
48c6bd0
Compare
48c6bd0 to
32caa19
Compare
|
Fresh rebase with 28e3787 |
manzoorwanijk
left a comment
There was a problem hiding this comment.
I think we need a changelog entry, making this one a breaking change.
32caa19 to
0ec12d1
Compare
True, added the |
|
@aduth do you have any roadmap in mind to work around this? |
|
I think we definitely need to fix this. Some of the other work around this (like #80706) only really indirectly solve some of the symptoms, but the impact of I think it'd be good to have a review here from @jsnajdr , who has been leading a lot of the work around the React 19 upgrade. |
| /* eslint-enable react/no-deprecated */ | ||
| } from 'react-dom'; | ||
| import { createRoot, hydrateRoot } from 'react-dom/client'; | ||
| } = ReactDOM; |
There was a problem hiding this comment.
Why do we need to reorganize this import?
There was a problem hiding this comment.
It's not a cosmetic reorganization.
React 19 removed findDOMNode, render, hydrate, and unmountComponentAtNode from react-dom.
With static named imports, those bindings must be resolvable at module link time. When a consumer loads @wordpress/element in a R19 app, the ESM loader tries to bind names that no longer exist on react-dom and throws for example:
SyntaxError: The requested module 'react-dom' does not provide an export named 'render'
Solution: A namespace import like this.
There was a problem hiding this comment.
Thanks, that makes sense. import { render } throws, but accessing a property of the namespace object (ReactDOM.render) just returns undefined.
Which ESM runtime does throw exactly this error? The native ESM resolver in Node, or in browsers? Or a bundler (esbuild or webpack) runtime?
SyntaxError: The requested module 'react-dom' does not provide an export named 'render'
3f416ac to
9ff36a0
Compare
jsnajdr
left a comment
There was a problem hiding this comment.
Thanks, now the element React dependencies are aligned with how other packages declare them and don't do anything special. And are compatible with React 19. Nice.
What?
Follow up to #80024
Makes
@wordpress/elementimportable under React 19 and widens the React peer ranges of the design-system packages likeuiandthemeto accept React 18 or 19.The idea is to do a smaller working iteration rather than having to wait for a fully React 19 compliant build, which may take long and doesn't seem to be landing anywhere near WP 7.1 according to #71336
Two changes in
@wordpress/element:src/react-platform.tsno longer uses named imports for APIs that React 19 removed fromreact-dom(findDOMNode,render,hydrate,unmountComponentAtNode).react,react-domand their types move fromdependenciestopeerDependencies(^18.0.0 || ^19.0.0), matching every sibling package.^18.0.0->^18.0.0 || ^19.0.0) in the five design-system packages.Why?
As a consumer running the design-system packages
uiandthemein a React 19 app, the use case tracked in #76941. I find two problems:Problem 1:
@wordpress/elementcrashes at load time under React 19. React 19 deleted these four exports from react-dom, so the module fails before any code runs:Problem 2: Declaring React as a hard dependency creates a second React. For some reason I don't understand,
elementis the only package in this family declaring react/react-dom as dependencies.How?
Removing API from
react-dominstead of named-importing them:Testing Instructions
Create a React 18 project consuming @wordpress/element: no change:
createRoot,createPortal,flushSyncwork, and the deprecatedrender/findDOMNodestill function as before.Create a React 19 project:
import { createRoot } from '@wordpress/element'now loads and works🐞 Previously:
SyntaxErrorat import.