-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Scripts: Enable React Fast Refresh for block development #28273
Conversation
Size Change: 0 B Total Size: 1.12 MB ℹ️ View Unchanged
|
60ab39e
to
e225f63
Compare
5423c71
to
346e856
Compare
346e856
to
8803be2
Compare
The current status can be summarized with the following demo: react-fast-refresh.movIt works perfectly fine for JavaScript files when developing a block 🎉 There are some issues with how webpack 4 works when |
That's awesome, thanks! I had trouble getting it setup on a site that's served from a local domain w/ SSL (e.g., |
I guess this line needs to be improved in the webpack config:
I'm also not too fond of: headers: {
// Requests come from the WP port.
'Access-Control-Allow-Origin': '*',
}, So it's definitely where it would have to improve to support different scenarios available other than using |
Ah, yeah, that got me further. It looks like changes are need to both diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js
index c33d154..5eb2655 100644
--- a/packages/scripts/config/webpack.config.js
+++ b/packages/scripts/config/webpack.config.js
@@ -8,6 +8,9 @@ const path = require( 'path' );
const ReactRefreshWebpackPlugin = require( '@pmmmwh/react-refresh-webpack-plugin' );
const TerserPlugin = require( 'terser-webpack-plugin' );
+const fs = require( 'fs' );
+
/**
* WordPress dependencies
*/
@@ -89,7 +92,9 @@ const config = {
// are used on the same page.
// @see https://github.com/WordPress/gutenberg/issues/23607
jsonpFunction: getJsonpFunctionIdentifier(),
- publicPath: `http://localhost:${ DEV_SERVER_PORT }/build/`,
+ publicPath: `https://learn.wordpress.test:${ DEV_SERVER_PORT }/build/`,
},
resolve: {
alias: {
@@ -255,10 +260,20 @@ if ( ! isProduction ) {
headers: {
// Requests come from the WP port.
'Access-Control-Allow-Origin': '*',
},
liveReload: false,
+ host: 'learn.wordpress.test',
port: DEV_SERVER_PORT,
writeToDisk: true,
+
+ https: {
+ key: fs.readFileSync( '/Users/iandunn/vhosts/localhost/learn.wordpress.test/learn.wordpress.test-key.pem' ),
+ cert: fs.readFileSync( '/Users/iandunn/vhosts/localhost/learn.wordpress.test/learn.wordpress.test.pem' ),
+ ca: fs.readFileSync( '/Users/iandunn/Library/Application Support/mkcert/rootCA.pem' )
+ }
};
} I just hardcoded those for testing, but plugins could set cross-environment things by overriding That gets rid of the JS-related console errors during the initial page load. I still get errors about stylesheets, but that seems to be expected at the moment. I haven't gotten it working with updates, though. Each save to
The watcher sees the edit to |
It looks like you can set some of those custom settings with CLI, not sure how it would work with
Yes, it might be because of issues with CSS imports. In my testing, I removed all references to all files that match |
864727c
to
59b9e5f
Compare
I rebased this branch with the latest changes from Resolves issuesI managed to resolve two known issues that existed before sp CSS reloading works perfectly fine in this branch:
New issuesIt looks like hot reloading still works for JavaScript changes, but it doesn't refresh updated React components anymore. At least for my test scenario: npx wp-create-block gutenpride --no-wp-scripts -t wp-block-directory-template
cd gutenpride
../node_modules/.bin/wp-scripts start --hot The comment with the default webpack config shortcomings is still relevant: #28273 (comment). |
@nicholasio, I'm very excited to see it being implemented at 10up 🎉 I'm happy to help you to make it work so we could learn from each other.
It depends on the browser used. It isn't necessary in Chome when React Developer Tools are enabled. I see a comment from @fabiankaegy in the PR referenced above that there are some issues in Safari. I left the following comment there:
|
@gziolo Thanks for following up. re: |
@shivapoudel I'm also trying to get this working with LocalWP but without much success. No matter what settings I use it doesn't hot reload. Is this still working for you? I'm on Windows and am beginning to wonder if this is a factor too. |
@dgwyer You have to activate the Gutenberg plugin to get this working, my friend :) |
It reminds me that we should bring the same scripts to WordPress core in the 6.0 release cycle. We still will need to put it behind the |
Brings the same functionality introduced in the Gutenberg plugin with WordPress/gutenberg#28273. In effect, it brings React Fast Refresh support to WordPress core for block development with `@wordpress/scripts`. Props walbo, antonvlasenko. See #51750, #55505. Follow-up [53135]. git-svn-id: https://develop.svn.wordpress.org/trunk@53140 602fd350-edb4-49c9-b593-d223f7449a82
Brings the same functionality introduced in the Gutenberg plugin with WordPress/gutenberg#28273. In effect, it brings React Fast Refresh support to WordPress core for block development with `@wordpress/scripts`. Props walbo, antonvlasenko. See #51750, #55505. Follow-up [53135]. Built from https://develop.svn.wordpress.org/trunk@53140 git-svn-id: http://core.svn.wordpress.org/trunk@52729 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Brings the same functionality introduced in the Gutenberg plugin with WordPress/gutenberg#28273. In effect, it brings React Fast Refresh support to WordPress core for block development with `@wordpress/scripts`. Props walbo, antonvlasenko. See #51750, #55505. Follow-up [53135]. Built from https://develop.svn.wordpress.org/trunk@53140 git-svn-id: https://core.svn.wordpress.org/trunk@52729 1a063a9b-81f0-0310-95a4-ce76da25c4cd
It works now also with WordPress 6.0 with the |
@gziolo I set When I update the code (React) of my block, the page refreshes instead of applying the update. Edit: |
Setting up the connection between the WordPress instance and the dev server is the worst. Unfortunately, I don't have enough experience with that part 😞 |
I found a solution. I'm using Docker and the site in the localhost subdomain works in the browser, but there was no this subdomain in the |
@shivapoudel @dgwyer I know I'm late to the party but I can't get this to work in LocalWP, tried all of the solutions in the post I think. Currently my script has this: "start:hot": "wp-scripts start --hot --host officehours.local --allowed-hosts all" It looks like it starts:
But then I see nothing on the Server URL?
Apologies if I'm missing something obvious! Would love to see this working 😅 |
I didn't get this working in LocalWP either. Haven't tried for a while though.
Did you mean you got it to work with wp-env (which is Docker based), or your own Docker solution? Would love to learn more about this. |
@gziolo any idea on #28273 (comment) and if not, do you think it's worth creating a separate issue? thanks! |
My own Docker solution based on this: https://github.com/litespeedtech/ols-docker-env So, it doesn't work: But it works: With wp-env, both versions works ¯_(ツ)_/¯ |
This comment was marked as resolved.
This comment was marked as resolved.
I finally found a solution (at least for me)! The problem is caused by multiple entry points (I have multiple blocks in one plugin). You need to add the following code to optimization: {
runtimeChunk: 'single',
}, For example: const defaultConfig = require('@wordpress/scripts/config/webpack.config');
const { getWebpackEntryPoints } = require('@wordpress/scripts/utils/config');
const isProduction = process.env.NODE_ENV === 'production';
const config = {
...defaultConfig,
entry: {
...getWebpackEntryPoints(),
index: './src/index.ts',
},
};
if (!isProduction) {
// Fix HMR
config.optimization = {
...defaultConfig.optimization,
runtimeChunk: 'single',
};
}
module.exports = config; This creates an additional add_action( 'enqueue_block_assets', function () {
$runtime_asset_path = plugin_dir_path( __FILE__ ) . 'build/runtime.asset.php';
if ( file_exists( $runtime_asset_path ) ) {
$runtime_asset = require $runtime_asset_path;
wp_enqueue_script(
'my-plugin-runtime',
plugin_dir_url( __FILE__ ) . 'build/runtime.js',
$runtime_asset['dependencies'],
$runtime_asset['version'],
);
}
} ); |
Nice work, thanks for sharing. |
It took me some time to find my old comment about using runtime chunk added in a different place: #25188 (comment). Thank you for sharing your findings. It looks like it still works. It would be great to have this runtime always present in the development mode when using hot module replacement. The only challenge would be to integrate the script enqueuing somehow with
I don't think I can help much here. Have you tried accessing the |
Hi @gziolo been playing with this a bit today:
I created a new site in LocalWP, called tests1.local I have an example plugin running inside it: As you can see I've added a Starting scriptI've added the following script to
When I start it, this is the output wp-content/plugins/example-dynamic is 📦 v0.1.0 via ⬢ v19.7.0 via 🐘 v8.1.9
➜ npm run start:hot
> example-dynamic@0.1.0 start:hot
> wp-scripts start --webpack-copy-php --hot
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Server: http://tests1.local:8887/
<i> [webpack-dev-server] Loopback: http://[::1]:8887/
<i> [webpack-dev-server] Content not from webpack is served from '/Users/eduwass/Sites/tests1/app/public/wp-content/plugins/example-dynamic/public' directory
assets by chunk 519 KiB (name: index)
asset index.js 518 KiB [emitted] (name: index) 1 related asset
asset index.css 959 bytes [emitted] (name: index) 1 related asset
asset index.asset.php 167 bytes [emitted] (name: index)
asset ./style-index.css 1 KiB [emitted] (name: ./style-index) (id hint: style) 1 related asset
asset block.json 503 bytes [emitted] [from: src/block.json] [copied]
asset render.php 149 bytes [emitted] [from: src/render.php] [copied]
Entrypoint index 520 KiB (537 KiB) = ./style-index.css 1 KiB index.css 959 bytes index.js 518 KiB index.asset.php 167 bytes 3 auxiliary assets Build folderI am able to access files from the
So it seems like webpack is connect properly? Also this:
...is also true, if I create a
It's like webpack is there serving the correct files, but the connection with the browser is not working? |
I'm not quite sure how to approach this, an issue may be needed, but I'm not too sure what exactly the issue is and thus how to indicate what needs to be fixed exactly. I've been trying to get fast refresh working, maybe it's because the package itself is unstable (as indicated by the authors) but... In a project with no changes and multiple blocks:
After making changes as suggested by @rafaucau :
I'd like to get this working properly, and contribute back to these scripts as they are extremely useful - any direction would be greatly appreciated so I can open a new issue with clearer details and possibly attempt at fixing this. Edit:
So far it has solved all of my issues without the need to modify anything. |
@jlandrum, thank you so much for sharing your use case and the way you approached moving forward by building only a single block at the time. It's a known limitation that we would like to resolve finally. I recently opened a pike PR against WordPress Core seeking a way to introduce shared scripts: WordPress/wordpress-develop#5118. So there are two ideas discussed currently:
@jsnajdr might have some more thoughts to add on how we can address this recurring issue. Once we have it sorted out, we can also explore how to improve hot module reloading for the code that is outside React components. In particular,
This is coming from this "optimization": gutenberg/packages/scripts/config/webpack.config.js Lines 129 to 142 in f35837b
If I remember correctly, the idea was that there is a single style file extracted for every entry point so the names don't conflict if the JS files end up in the same folder. However, this might not make sense anymore, and it could benefit from an update. The initial reasoning seems to be captured in https://github.com/WordPress/gutenberg/tree/trunk/packages/scripts#using-css. It feels like enforcing a separate folder for every entry point would allow us having something like |
Description
Part of #21008 targeting
@wordpress/scripts
.I followed instructions at https://github.com/pmmmwh/react-refresh-webpack-plugin and it fully works as expected for Chrome and Safari. It should work with both React Developer Tools enabled but also without them.
I was testing with
SCRIPT_DEBUG
set totrue
for WordPress to ensure that development versions ofreact
andreact-dom
were served. In general, the challenge is that we are using externals for both libraries, while in the examples shared they are all bundled together.At the moment React Refresh needs to be activated with the
--hot
flag when executing thestart
command from@wordpress/scripts
:If the flag is not provided then the
start
command should work as before.Resolved Blockers
MiniCSSExtractPlugin
but it should with webpack 5, see https://webpack.js.org/plugins/mini-css-extract-plugin/#hot-module-reloading-hmr.MiniCSSExtractPlugin
andsplitChunks
config for thestyle.scss
filesAddreact/jsx-runtime
entry for the new automatic JSX transform from React 17 Addjsx-runtime
entry for the new automatic JSX transform #34221How has this been tested?
The way I test it:
npx wp-create-block my-block --no-wp-scripts cd my-block ../node_modules/.bin/wp-scripts start --hot
This is to ensure that we are using the latest
@wordpress/scripts
from the branch and with the default webpack config from@wordpress/scripts
.Ensure your WordPress instance has
SCRIPT_DEBUG
set totrue
.Screenshots
React.Refresh.Safari.mov
React.Refresh.Chrome.and.Safari.mov
Types of changes
New feature (non-breaking change which adds functionality).
Checklist: