Skip to content
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

HMR not working in WordPress when React loaded externally #443

Closed
rob opened this issue Jul 5, 2021 · 6 comments
Closed

HMR not working in WordPress when React loaded externally #443

rob opened this issue Jul 5, 2021 · 6 comments

Comments

@rob
Copy link

rob commented Jul 5, 2021

This is probably related to #334; I've been following that thread closely.

Everything (webpack-dev-server proxying to WordPress + HMR) works great if React is bundled, but trying the suggestions above (and looking at your CodePen example) to load React externally is giving me an issue when trying to use HMR (React is loading fine.)

Basically, the console will show the module was updated, but nothing visual happens. Watching the DOM as I made the change, I did see the hot-update.js <script> file briefly included in the and then removed:

Screen Shot 2021-07-05 at 16 58 19

And the files shows up in the network tab:

Screen Shot 2021-07-05 at 17 17 20

But it looks like the <script> for them is being removed right away (not sure if the ":undefined" in the data-webpack part is an issue as well.) If I refresh the page, the changes show obviously.

It's kind of hard to show everything, but here's a Gist of my webpack.config.js:

https://gist.github.com/rob/41ec67141c78f4104e12183a0d327cdd

And lastly, here's a very short video showing me saving the file and the <script> tag flashing quickly in the console:

https://streamable.com/cthzcb

And if it helps, the WordPress plugin is set up to output all of these files individually like in your CodePen example (there's some extra WP-specific ones here, but you can see everything):

image

Any idea what could be the issue? Thanks for the help and I appreciate all the work you've done!

@pmmmwh
Copy link
Owner

pmmmwh commented Jul 6, 2021

Does the defaultVendors chunk include any React code? I think that could be the issue.

Actually right now maybe I would advocate more for not externalising React in development simply because of its simplicity to setup ... it is unfortunate how complex things can quickly become.

@rob
Copy link
Author

rob commented Jul 6, 2021

Does the defaultVendors chunk include any React code? I think that could be the issue.

Actually right now maybe I would advocate more for not externalising React in development simply because of its simplicity to setup ... it is unfortunate how complex things can quickly become.

I don't see anything loaded from ./node_modules/react/ or ./node_modules/react-dom/ in defaultVendors?

Kind of related, I was using this example to load react/react-dom externally, but WordPress has its own @wordpress/element wrapper around React/ReactDOM I was trying to use originally, here's their example:

<div id="greeting"></div>
<script>
	function Greeting( props ) {
		return wp.element.createElement(
			'span',
			null,
			'Hello ' + props.toWhom + '!'
		);
	}

	wp.element.render(
		wp.element.createElement( Greeting, { toWhom: 'World' } ),
		document.getElementById( 'greeting' )
	);
</script>

But I had no idea how to get that to work either with hot reload and wasn't sure if solving one would solve the other. Basically, WP will load react.js, react-dom.js, and element.js and make wp.element (wrapper for React/ReactDOM) a global variable you can use.

After playing for two days, it seems it might be better to just not do all of this and use an external React as you said, lol.

@pmmmwh
Copy link
Owner

pmmmwh commented Jul 7, 2021

Ah ... are you using the development build of React and React DOM when you externalise? If you don't mind I can take a look at a reproduction and help out, but definitely internalising React during development seems like a fair tradeoff.

@rob
Copy link
Author

rob commented Jul 7, 2021

I have a repo here, but it's meant to be used as a WordPress plugin.

I think the issue is 'solved' for me now; I have HMR working using @wordpress/element in development (which bundles react/react dom with it), and it's excluded when building for production and uses the global 'wp.element' variable instead. So the production build js is nice and light.

// ./src/index.js
import { render } from '@wordpress/element'
import App from './components/App.js'

// becomes wp.element.render() in production
render(<App />, document.getElementById('wp-plugin-react-base'))
// ./webpack.config.js
const productionConfig = {
    mode: 'production',
    devtool: 'source-map',

    externals: {
        '@wordpress/element': 'wp.element'
    }
}

Seems a lot easier than trying to use the external wp.element global variable and get HMR working locally.

@pmmmwh
Copy link
Owner

pmmmwh commented Jul 11, 2021

Yep I think this is the simpler way to go without having to mess with the internals of @wordpress/element.

Feel free to close the issue if you think this is "solved".

@rob
Copy link
Author

rob commented Jul 11, 2021

Will close. Thanks again for all your work!

@rob rob closed this as completed Jul 11, 2021
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

No branches or pull requests

2 participants