mirror of
https://github.com/facebook/docusaurus.git
synced 2025-12-26 01:33:02 +00:00
fix(core): do not recreate ReactDOM Root, fix React warning on hot reload (#10103)
This commit is contained in:
parent
4159b25dd1
commit
2d8281fc03
|
|
@ -387,4 +387,5 @@ interface Window {
|
|||
prefetch: (url: string) => false | Promise<void[]>;
|
||||
preload: (url: string) => false | Promise<void[]>;
|
||||
};
|
||||
docusaurusRoot?: import('react-dom/client').Root;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, {startTransition} from 'react';
|
||||
import ReactDOM, {type ErrorInfo} from 'react-dom/client';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
import {HelmetProvider} from 'react-helmet-async';
|
||||
|
|
@ -46,21 +46,24 @@ if (ExecutionEnvironment.canUseDOM) {
|
|||
};
|
||||
|
||||
const renderApp = () => {
|
||||
if (window.docusaurusRoot) {
|
||||
window.docusaurusRoot.render(app);
|
||||
return;
|
||||
}
|
||||
if (hydrate) {
|
||||
React.startTransition(() => {
|
||||
ReactDOM.hydrateRoot(container, app, {
|
||||
onRecoverableError,
|
||||
});
|
||||
window.docusaurusRoot = ReactDOM.hydrateRoot(container, app, {
|
||||
onRecoverableError,
|
||||
});
|
||||
} else {
|
||||
const root = ReactDOM.createRoot(container, {onRecoverableError});
|
||||
React.startTransition(() => {
|
||||
root.render(app);
|
||||
});
|
||||
root.render(app);
|
||||
window.docusaurusRoot = root;
|
||||
}
|
||||
};
|
||||
|
||||
preload(window.location.pathname).then(renderApp);
|
||||
preload(window.location.pathname).then(() => {
|
||||
startTransition(renderApp);
|
||||
});
|
||||
|
||||
// Webpack Hot Module Replacement API
|
||||
if (module.hot) {
|
||||
|
|
|
|||
|
|
@ -45,46 +45,55 @@ const getChunkNamesToLoad = (path: string): string[] =>
|
|||
)
|
||||
.flatMap(([, routeChunks]) => Object.values(flat(routeChunks)));
|
||||
|
||||
const docusaurus = {
|
||||
prefetch(routePath: string): false | Promise<void[]> {
|
||||
if (!canPrefetch(routePath)) {
|
||||
return false;
|
||||
}
|
||||
fetched.add(routePath);
|
||||
type Docusaurus = Window['docusaurus'];
|
||||
|
||||
// Find all webpack chunk names needed.
|
||||
const matches = matchRoutes(routes, routePath);
|
||||
const prefetch: Docusaurus['prefetch'] = (
|
||||
routePath: string,
|
||||
): false | Promise<void[]> => {
|
||||
if (!canPrefetch(routePath)) {
|
||||
return false;
|
||||
}
|
||||
fetched.add(routePath);
|
||||
|
||||
const chunkNamesNeeded = matches.flatMap((match) =>
|
||||
getChunkNamesToLoad(match.route.path),
|
||||
);
|
||||
// Find all webpack chunk names needed.
|
||||
const matches = matchRoutes(routes, routePath);
|
||||
|
||||
// Prefetch all webpack chunk assets file needed.
|
||||
return Promise.all(
|
||||
chunkNamesNeeded.map((chunkName) => {
|
||||
// "__webpack_require__.gca" is injected by ChunkAssetPlugin. Pass it
|
||||
// the name of the chunk you want to load and it will return its URL.
|
||||
// eslint-disable-next-line camelcase
|
||||
const chunkAsset = __webpack_require__.gca(chunkName);
|
||||
const chunkNamesNeeded = matches.flatMap((match) =>
|
||||
getChunkNamesToLoad(match.route.path),
|
||||
);
|
||||
|
||||
// In some cases, webpack might decide to optimize further, leading to
|
||||
// the chunk assets being merged to another chunk. In this case, we can
|
||||
// safely filter it out and don't need to load it.
|
||||
if (chunkAsset && !chunkAsset.includes('undefined')) {
|
||||
return prefetchHelper(chunkAsset);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}),
|
||||
);
|
||||
},
|
||||
// Prefetch all webpack chunk assets file needed.
|
||||
return Promise.all(
|
||||
chunkNamesNeeded.map((chunkName) => {
|
||||
// "__webpack_require__.gca" is injected by ChunkAssetPlugin. Pass it
|
||||
// the name of the chunk you want to load and it will return its URL.
|
||||
// eslint-disable-next-line camelcase
|
||||
const chunkAsset = __webpack_require__.gca(chunkName);
|
||||
|
||||
preload(routePath: string): false | Promise<void[]> {
|
||||
if (!canPreload(routePath)) {
|
||||
return false;
|
||||
}
|
||||
loaded.add(routePath);
|
||||
return preloadHelper(routePath);
|
||||
},
|
||||
// In some cases, webpack might decide to optimize further, leading to
|
||||
// the chunk assets being merged to another chunk. In this case, we can
|
||||
// safely filter it out and don't need to load it.
|
||||
if (chunkAsset && !chunkAsset.includes('undefined')) {
|
||||
return prefetchHelper(chunkAsset);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const preload: Docusaurus['preload'] = (
|
||||
routePath: string,
|
||||
): false | Promise<void[]> => {
|
||||
if (!canPreload(routePath)) {
|
||||
return false;
|
||||
}
|
||||
loaded.add(routePath);
|
||||
return preloadHelper(routePath);
|
||||
};
|
||||
|
||||
const docusaurus: Window['docusaurus'] = {
|
||||
prefetch,
|
||||
preload,
|
||||
};
|
||||
|
||||
// This object is directly mounted onto window, better freeze it
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ datagit
|
|||
Datagit
|
||||
Datagit's
|
||||
dedup
|
||||
Déja
|
||||
devto
|
||||
dingers
|
||||
Dmitry
|
||||
|
|
|
|||
Loading…
Reference in New Issue