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

[Fast Refresh] Support injecting runtime after renderer executes #17633

Merged
merged 1 commit into from
Dec 17, 2019

Conversation

gaearon
Copy link
Collaborator

@gaearon gaearon commented Dec 17, 2019

I think this fixes #17626 and #17552.

I was assuming that Fresh runtime always executes before the renderer. But on the web this won't be the case if you load React from CDN and then run your webpack bundle (pmmmwh/react-refresh-webpack-plugin#13). And separating <script> tags can be annoying and complicated.

Instead, we can handle the simple case — when ReactDOM executes before the webpack bundle — gracefully. The DevTools global hook already has a renderers map so all we need to connect to them is to read from it. In fact that's how DevTools backends themselves connect to already injected renderers.

This still doesn't handle the case where you mount some roots before injecting the runtime. In that case they won't be "visible" to Fresh. Arguably this is more of a corner case and I wouldn't bother solving this yet. The webpack plugin should be able to ensure that injection happens before the actual app code runs.

I added a regression test.

@@ -435,6 +435,7 @@ export function injectIntoGlobalHook(globalObject: any): void {
// Otherwise, the renderer will think that there is no global hook, and won't do the injection.
let nextID = 0;
globalObject.__REACT_DEVTOOLS_GLOBAL_HOOK__ = hook = {
renderers: new Map(),
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is just so the lines below don't crash when we take this code branch. This particular Map isn't actually used further.

@@ -468,6 +469,19 @@ export function injectIntoGlobalHook(globalObject: any): void {
return id;
};

// Do the same for any already injected roots.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Note this is almost copy paste from the code above (462–468). I could extract a function but meh.

@codesandbox-ci
Copy link

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 43c8eff:

Sandbox Source
damp-water-609v6 Configuration

@sizebot
Copy link

sizebot commented Dec 17, 2019

Details of bundled changes.

Comparing: 7c21bf7...43c8eff

react-refresh

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-refresh-babel.production.min.js 0.0% -0.0% 7.19 KB 7.19 KB 2.57 KB 2.57 KB NODE_PROD
react-refresh-runtime.development.js +2.6% +2.1% 17.95 KB 18.41 KB 5.38 KB 5.49 KB NODE_DEV
react-refresh-runtime.production.min.js 0.0% -0.4% 368 B 368 B 264 B 263 B NODE_PROD
react-refresh-babel.development.js 0.0% -0.0% 24.06 KB 24.06 KB 5.49 KB 5.49 KB NODE_DEV

Size changes (stable)

Generated by 🚫 dangerJS against 43c8eff

@sizebot
Copy link

sizebot commented Dec 17, 2019

Details of bundled changes.

Comparing: 7c21bf7...43c8eff

react-refresh

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-refresh-babel.development.js 0.0% -0.0% 24.07 KB 24.07 KB 5.5 KB 5.5 KB NODE_DEV
react-refresh-babel.production.min.js 0.0% -0.0% 7.2 KB 7.2 KB 2.58 KB 2.58 KB NODE_PROD
ReactFreshRuntime-dev.js +2.7% +2.0% 18 KB 18.49 KB 5.37 KB 5.48 KB FB_WWW_DEV
react-refresh-runtime.development.js +2.6% +2.1% 17.96 KB 18.42 KB 5.39 KB 5.5 KB NODE_DEV
react-refresh-runtime.production.min.js 0.0% -0.4% 381 B 381 B 273 B 272 B NODE_PROD

Size changes (experimental)

Generated by 🚫 dangerJS against 43c8eff

@gaearon gaearon merged commit c2d1561 into facebook:master Dec 17, 2019
@gaearon gaearon deleted the fff branch December 17, 2019 13:49
@leidegre
Copy link
Contributor

I can't get it to work unless I enable React Development Tools, is this expected behavior? Not a big deal but I can't seem to get it to do it's magic unless React Development Tools is runnig.

@gaearon
Copy link
Collaborator Author

gaearon commented Aug 30, 2020

Sorry, not enough details. Please file a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

react-refresh + ReactDOM: hot reloading only works when bundling React
6 participants