Skip to content

Copy React vendor scripts from Gutenberg, update version number#11359

Open
jsnajdr wants to merge 3 commits into
WordPress:trunkfrom
jsnajdr:update/copy-react-from-gutenberg
Open

Copy React vendor scripts from Gutenberg, update version number#11359
jsnajdr wants to merge 3 commits into
WordPress:trunkfrom
jsnajdr:update/copy-react-from-gutenberg

Conversation

@jsnajdr

@jsnajdr jsnajdr commented Mar 26, 2026

Copy link
Copy Markdown
Member

Gutenberg started building its own bundles for the react, react-dom and react-jsx-runtime vendor scripts. Previously we've been copying React's own UMD bundles shipped as part of their NPM packages, but React 19 is going to remove these UMD bundles, and we are preparing for the migration by abandoning the UMD bundles in advance.

Instead of copying the UMD files, we copy them from the Gutenberg build.

We also update the version strings of the packages by appending a -wp suffix, so that we can differentiate them from previous versions. Even though it's still the same React 18.3.1, the build method has changed.

Trac ticket: https://core.trac.wordpress.org/ticket/64958
Backports Gutenberg PR: WordPress/gutenberg#74343 and WordPress/gutenberg#76811

Use of AI Tools

Autocomplete with Cursor and Opus 4.6.

@github-actions

github-actions Bot commented Mar 26, 2026

Copy link
Copy Markdown

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 props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props jsnajdr, ramonopoly, desrosj, mamaduka, wildworks, youknowriad.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@ramonjd ramonjd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for prepping this @jsnajdr 🙇🏻

This builds locally for me without complaint, the vendor dist files have the right param.

Image

Might need a rebase before we can commit.

Comment thread tests/phpunit/tests/dependencies/scripts.php Outdated
Comment thread tests/phpunit/tests/dependencies/scripts.php Outdated
@Mamaduka

Copy link
Copy Markdown
Member

We also update the version strings of the packages by appending a -wp suffix, so that we can differentiate them from previous versions. Even though it's still the same React 18.3.1, the build method has changed.

We should probably get wider feedback on this new suffix. IIRC, WP always used version numbers for scripts, but vendors might be excluded from this policy.

cc @desrosj, @peterwilsoncc

@desrosj
desrosj self-requested a review March 30, 2026 23:34
@desrosj

desrosj commented Apr 1, 2026

Copy link
Copy Markdown
Member

Noting that I've seen this and it's on my list, but there are still build script bugs that need to be ironed out for 7.0. So I'm prioritizing those first.

@jsnajdr
jsnajdr force-pushed the update/copy-react-from-gutenberg branch from a8dfbc1 to eaebcd0 Compare April 8, 2026 14:50
@jsnajdr
jsnajdr force-pushed the update/copy-react-from-gutenberg branch from eaebcd0 to a37b80d Compare June 29, 2026 08:09
@t-hamano

Copy link
Copy Markdown
Contributor

I would appreciate it if we could confirm whether this PR is ready to ship for 7.1 Beta1.

@jsnajdr

jsnajdr commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

A similar question was raised and answered on Trac (https://core.trac.wordpress.org/ticket/64958#comment:8) and the answer is yes, the PR is relevant and ready to be approved and shipped.

@t-hamano

Copy link
Copy Markdown
Contributor

@Mamaduka @desrosj, could you re-review this PR?

@desrosj

desrosj commented Jul 13, 2026

Copy link
Copy Markdown
Member

I will take a look in the next 24 hours.

@desrosj desrosj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @jsnajdr!

I believe that the react and react-dom dependencies can be removed from the package.json file. But I could be missing a reason why they are still defined there.

Also, the react-is package is listed as a dependency. It looks like that was first added in cf8b74d#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519, but I can't find any record of it being referenced in any of the build tools/scripts in this repository. Was this included on accident? Or is there a reason for this that is not immediately clear to me?

Also, a few questions.

  • Will there be a situation where someone would like the standard React asset and not the UMD format that we're continuing to provide?
  • If so, how would someone deal with this? Would it be beneficial for Core to include both with different script handles to prevent situations where someone just takes over the react/react-dom ones?

Comment thread Gruntfile.js
Comment on lines -458 to -464
// React libraries: react, react-dom
{
[ WORKING_DIR + 'wp-includes/js/dist/vendor/react.js' ]: [ './node_modules/react/umd/react.development.js' ],
[ WORKING_DIR + 'wp-includes/js/dist/vendor/react.min.js' ]: [ './node_modules/react/umd/react.production.min.js' ],
[ WORKING_DIR + 'wp-includes/js/dist/vendor/react-dom.js' ]: [ './node_modules/react-dom/umd/react-dom.development.js' ],
[ WORKING_DIR + 'wp-includes/js/dist/vendor/react-dom.min.js' ]: [ './node_modules/react-dom/umd/react-dom.production.min.js' ],
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a reason why just changing these source paths would not work? If the paths are updated like this, then the entire if block in copy.js can be removed.

					// React libraries: react, react-dom
					{
						[ WORKING_DIR + 'wp-includes/js/dist/vendor/react.js' ]: [ './gutenberg/build/scripts/vendors/react.js' ],
						[ WORKING_DIR + 'wp-includes/js/dist/vendor/react.min.js' ]: [ './gutenberg/build/scripts/vendors/react.min.js' ],
						[ WORKING_DIR + 'wp-includes/js/dist/vendor/react-dom.js' ]: [ './gutenberg/build/scripts/vendors/react-dom.js' ],
						[ WORKING_DIR + 'wp-includes/js/dist/vendor/react-dom.min.js' ]: [ './gutenberg/build/scripts/vendors/react-dom.min.js' ],
						[ WORKING_DIR + 'wp-includes/js/dist/vendor/react-jsx-runtime.js' ]: [ './gutenberg/build/scripts/vendors/react-jsx-runtime.js' ],
						[ WORKING_DIR + 'wp-includes/js/dist/vendor/react-jsx-runtime.min.js' ]: [ './gutenberg/build/scripts/vendors/react-jsx-runtime.min.js' ],
					},

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In the current code layout is quite clear that all the copying from gutenberg/build is done in the tools/gutenberg/copy.js script. The Gruntfile only handles other sources.

The only exception are the changes you did recently in 49d8c11 (Build/Test Tools: Remove the requirement to clone/build Gutenberg). That patch starts to do some Gutenberg copying (pages, routes, modules) in the Gruntfile.

What was the purpose of splitting the Gutenberg build copy into two places like this? Intentional start of some gradual migration, or was it accidental?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The only exception are the changes you did recently in 49d8c11 (Build/Test Tools: Remove the requirement to clone/build Gutenberg). That patch starts to do some Gutenberg copying (pages, routes, modules) in the Gruntfile.

This is not entirely true. There are a number of Gutenberg-sourced assets that are handled by Grunt:

The only assets currently managed in the copy.js script are the block-related files and script files. 49d8c11 was the first commit, but there have been many since.

This is another discussion to have, but as much as possible we should avoid having multiple tools responsible for the same tasks. While Grunt is certainly considered legacy, it is battle tested, already familiar to the broad contributing community, and still reliably performs the operations that are required by the build script. The copy.js file reinvented the wheel for many of those operations and contained many nuanced bugs that quite difficult to track down, causing many headaches. Ideally, copy.js should go away entirely so that there's a single build tool responsible for all build operations. And in the end, this would actually make it easier to migrate off of Grunt once there is a compelling case to do so.

Previously, it appeared that Webpack was a good candidate for that (see Core-43731). But that never gained traction, and 22294af actually ripped almost all of the Webpack steps out (which also left us now with 3 different tools responsible for build tasks).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OK, I moved the vendors copy back to the Gruntfile, only changing the source paths and adding react-jsx-runtime.

@jsnajdr

jsnajdr commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

I believe that the react and react-dom dependencies can be removed from the package.json file.

@wordpress/* packages and others typically declare react as a peer dependency, and then it's up to the consuming package to provide that peer. In such cases it's correct for package.json to declare it, even if there is not direct usage.

Also, the react-is package is listed as a dependency.

Maybe @youknowriad remembers why he needed to add it in this commit 2 years ago. A typical reason is to pin the exact version, or to provide a peer dependency.

One interesting thing about that 2 years old commit is that at the time the root package.json declared many @wordpress/* dependencies. Packages with Gutenberg code, not just tooling. Today they are no longer there. I don't know what has changed.

It's quite likely that the package.json dependencies are no longer needed, but I think it's off topic for this PR. I'm a bit worried about entering some NPM dependency rabbit hole.

Will there be a situation where someone would like the standard React asset and not the UMD format that we're continuing to provide?

I'm not aware of any situation where a consumer would observe a difference between the old-style and new-style asset.

@t-hamano

Copy link
Copy Markdown
Contributor

@jsnajdr, Should this PR be committed before the 7.1 beta1 release, or is it okay for beta2? This is because the beta 1 release is only an hour away.

@youknowriad

Copy link
Copy Markdown
Contributor

It's quite likely that the package.json dependencies are no longer needed, but I think it's off topic for this PR. I'm a bit worried about entering some NPM dependency rabbit hole.

Today WordPress doesn't consume Gutenberg packages and code from npm, instead they're downloaded from a zip of a built Gutenberg basically.

@desrosj

desrosj commented Jul 15, 2026

Copy link
Copy Markdown
Member

Today WordPress doesn't consume Gutenberg packages and code from npm, instead they're downloaded from a zip of a built Gutenberg basically.

Do you recall any of the context around when react-is was added as a dependency here? I can't find where it was ever consumed by the build processes. And it seems like it's currently compiled into the built version that we now maintain.

I'm uncertain if it's good practice to note something as a dependency in package.json even when it's not actually required for the building and publishing process (which would make then make sense for it being included), or if it was included accidentally.

@desrosj

desrosj commented Jul 15, 2026

Copy link
Copy Markdown
Member

@wordpress/* packages and others typically declare react as a peer dependency, and then it's up to the consuming package to provide that peer. In such cases it's correct for package.json to declare it, even if there is not direct usage.

Actually, that may be what @jsnajdr is saying here? But I'm not clear if this is still the case for all three of these listed dependencies (react, react-dom, react-is).

@jsnajdr

jsnajdr commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

Should this PR be committed before the 7.1 beta1 release, or is it okay for beta2?

Beta 2 is fine, this is not urgent. It's a preparation for future React 19 migration.

@youknowriad

youknowriad commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Do you recall any of the context around when react-is

I'm afraid not, my guess is npm version conflicts but I can't tell for sure at the moment.

@jsnajdr
jsnajdr force-pushed the update/copy-react-from-gutenberg branch from b6f3944 to 642e634 Compare July 16, 2026 09:02
@jsnajdr

jsnajdr commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

I pushed a commit that removes the react, react-dom and react-is dependencies. They are most likely a leftover from times when the project did its own build of Gutenberg. Now when we just download and unpack a ZIP file, they are no longer needed.

I also removed part of unit tests that checks the registered script versions against versions in package.json. React is no longer sourced from node_modules, so that check is no longer relevant.

Comment thread tools/gutenberg/copy.js
// Rename vendors/ to vendor/ when copying.
directoryRenames: {
vendors: 'vendor',
},

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

These params were used only by the vendors copy task, and that has been moved to Gruntfile now.

@jsnajdr
jsnajdr force-pushed the update/copy-react-from-gutenberg branch from a67da16 to 8f71142 Compare July 16, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants