From 318471d547faf17013890b373dd08968e438591a Mon Sep 17 00:00:00 2001 From: Sanjaiyan Parthipan Date: Sun, 31 Jul 2022 13:31:31 +0530 Subject: [PATCH 1/8] =?UTF-8?q?Adding=20incremental=20support=20for=20Reac?= =?UTF-8?q?t=2018=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/docusaurus/package.json | 4 +- .../docusaurus/src/client/clientEntry.tsx | 78 ++++++++++++++----- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json index 965856e2f7..6ee458d4e5 100644 --- a/packages/docusaurus/package.json +++ b/packages/docusaurus/package.json @@ -121,8 +121,8 @@ "tree-node-cli": "^1.5.2" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^16.8.4 || ^17.0.0 || ^18.0.0-0", + "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0-0" }, "engines": { "node": ">=16.14" diff --git a/packages/docusaurus/src/client/clientEntry.tsx b/packages/docusaurus/src/client/clientEntry.tsx index 8e53d92e10..4b61ba61b6 100644 --- a/packages/docusaurus/src/client/clientEntry.tsx +++ b/packages/docusaurus/src/client/clientEntry.tsx @@ -5,19 +5,18 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; -import ReactDOM from 'react-dom'; -import {BrowserRouter} from 'react-router-dom'; -import {HelmetProvider} from 'react-helmet-async'; +import React from "react"; +import { BrowserRouter } from "react-router-dom"; +import { HelmetProvider } from "react-helmet-async"; -import ExecutionEnvironment from './exports/ExecutionEnvironment'; -import App from './App'; -import preload from './preload'; -import docusaurus from './docusaurus'; +import ExecutionEnvironment from "./exports/ExecutionEnvironment"; +import App from "./App"; +import preload from "./preload"; +import docusaurus from "./docusaurus"; declare global { interface NodeModule { - hot?: {accept: () => void}; + hot?: { accept: () => void }; } } @@ -29,18 +28,55 @@ if (ExecutionEnvironment.canUseDOM) { // first-load experience. // For development, there is no existing markup so we had to render it. // We also preload async component to avoid first-load loading screen. - const renderMethod = - process.env.NODE_ENV === 'production' ? ReactDOM.hydrate : ReactDOM.render; - preload(window.location.pathname).then(() => { - renderMethod( - - - - - , - document.getElementById('__docusaurus'), - ); - }); + + if (React.version.includes("18.")) { + if (process.env.NODE_ENV === "production") { + const { hydrateRoot } = require("react-dom/client"); + + preload(window.location.pathname).then(() => { + hydrateRoot( + document.getElementById("__docusaurus"), + + + + + + ); + }); + } else { + const { createRoot } = require("react-dom/client"); + + preload(window.location.pathname).then(() => { + const docReactRoot = createRoot( + document.getElementById("__docusaurus") + ); + + docReactRoot.render( + + + + + + ); + }); + } + } else { + const ReactDOM = require("react-dom"); + const renderMethod = + process.env.NODE_ENV === "production" + ? ReactDOM.hydrate + : ReactDOM.render; + preload(window.location.pathname).then(() => { + renderMethod( + + + + + , + document.getElementById("__docusaurus") + ); + }); + } // Webpack Hot Module Replacement API if (module.hot) { From 09e0f59bd7642529624b36c6552dc885eac41530 Mon Sep 17 00:00:00 2001 From: Sanjaiyan Parthipan Date: Mon, 19 Sep 2022 01:23:21 +0530 Subject: [PATCH 2/8] sanjaiyan: route announcer --- packages/docusaurus/src/client/App.tsx | 2 + .../src/client/exports/RouteAnnouncer.tsx | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 packages/docusaurus/src/client/exports/RouteAnnouncer.tsx diff --git a/packages/docusaurus/src/client/App.tsx b/packages/docusaurus/src/client/App.tsx index 8554f5b91a..76482d7c41 100644 --- a/packages/docusaurus/src/client/App.tsx +++ b/packages/docusaurus/src/client/App.tsx @@ -19,6 +19,7 @@ import {DocusaurusContextProvider} from './docusaurusContext'; import PendingNavigation from './PendingNavigation'; import BaseUrlIssueBanner from './BaseUrlIssueBanner'; import SiteMetadataDefaults from './SiteMetadataDefaults'; +import RouteAnnouncer from './exports/RouteAnnouncer'; // TODO, quick fix for CSS insertion order // eslint-disable-next-line import/order @@ -38,6 +39,7 @@ export default function App(): JSX.Element { {routeElement} + diff --git a/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx b/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx new file mode 100644 index 0000000000..c722112735 --- /dev/null +++ b/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import {useLocation} from "@docusaurus/router"; + +const docusaurusjsRouteAnnouncerStyles: React.CSSProperties = { + border: 0, + clip: "rect(0 0 0 0)", + height: "1px", + margin: "-1px", + overflow: "hidden", + padding: 0, + position: "absolute", + width: "1px", + whiteSpace: "nowrap", + wordWrap: "normal", +}; + +export const RouteAnnouncer = React.memo(() => { + const { pathname } = useLocation(); + const [routeAnnouncement, setRouteAnnouncement] = React.useState(""); + const previouslyLoadedPath = React.useRef(pathname); + + React.useEffect(() => { + if (previouslyLoadedPath.current === pathname) return; + previouslyLoadedPath.current = pathname; + + if (document.title) { + setRouteAnnouncement(document.title); + } else { + const pageHeader = document.querySelector("h1"); + const content = pageHeader?.innerText ?? pageHeader?.textContent; + + setRouteAnnouncement(content || pathname); + } + }, [asPath]); + + return ( + + ); +}); + +export default RouteAnnouncer; From 300e4e358d09faf9f347feb326ee7fb2543e6cac Mon Sep 17 00:00:00 2001 From: Sanjaiyan Parthipan Date: Mon, 19 Sep 2022 01:25:46 +0530 Subject: [PATCH 3/8] fix package.json --- packages/docusaurus/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json index 0d46f17a20..ab5e9df978 100644 --- a/packages/docusaurus/package.json +++ b/packages/docusaurus/package.json @@ -121,8 +121,8 @@ "tree-node-cli": "^1.5.2" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0 || ^18.0.0-0", - "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0-0" + "react": "^16.8.4 || ^17.0.0", + "react-dom": "^16.8.4 || ^17.0.0" }, "engines": { "node": ">=16.14" From 44aa476f04f4def9953dd6468c689f1bcf4bc004 Mon Sep 17 00:00:00 2001 From: Sanjaiyan Parthipan Date: Mon, 19 Sep 2022 01:26:29 +0530 Subject: [PATCH 4/8] fix old commits --- .../docusaurus/src/client/clientEntry.tsx | 125 +++++++----------- 1 file changed, 45 insertions(+), 80 deletions(-) diff --git a/packages/docusaurus/src/client/clientEntry.tsx b/packages/docusaurus/src/client/clientEntry.tsx index 4b61ba61b6..d21e15df1d 100644 --- a/packages/docusaurus/src/client/clientEntry.tsx +++ b/packages/docusaurus/src/client/clientEntry.tsx @@ -5,83 +5,48 @@ * LICENSE file in the root directory of this source tree. */ -import React from "react"; -import { BrowserRouter } from "react-router-dom"; -import { HelmetProvider } from "react-helmet-async"; - -import ExecutionEnvironment from "./exports/ExecutionEnvironment"; -import App from "./App"; -import preload from "./preload"; -import docusaurus from "./docusaurus"; - -declare global { - interface NodeModule { - hot?: { accept: () => void }; - } -} - -// Client-side render (e.g: running in browser) to become single-page -// application (SPA). -if (ExecutionEnvironment.canUseDOM) { - window.docusaurus = docusaurus; - // For production, attempt to hydrate existing markup for performant - // first-load experience. - // For development, there is no existing markup so we had to render it. - // We also preload async component to avoid first-load loading screen. - - if (React.version.includes("18.")) { - if (process.env.NODE_ENV === "production") { - const { hydrateRoot } = require("react-dom/client"); - - preload(window.location.pathname).then(() => { - hydrateRoot( - document.getElementById("__docusaurus"), - - - - - - ); - }); - } else { - const { createRoot } = require("react-dom/client"); - - preload(window.location.pathname).then(() => { - const docReactRoot = createRoot( - document.getElementById("__docusaurus") - ); - - docReactRoot.render( - - - - - - ); - }); - } - } else { - const ReactDOM = require("react-dom"); - const renderMethod = - process.env.NODE_ENV === "production" - ? ReactDOM.hydrate - : ReactDOM.render; - preload(window.location.pathname).then(() => { - renderMethod( - - - - - , - document.getElementById("__docusaurus") - ); - }); - } - - // Webpack Hot Module Replacement API - if (module.hot) { - // Self-accepting method/ trick - // (https://github.com/webpack/webpack-dev-server/issues/100#issuecomment-290911036) - module.hot.accept(); - } -} + import React from 'react'; + import ReactDOM from 'react-dom'; + import {BrowserRouter} from 'react-router-dom'; + import {HelmetProvider} from 'react-helmet-async'; + + import ExecutionEnvironment from './exports/ExecutionEnvironment'; + import App from './App'; + import preload from './preload'; + import docusaurus from './docusaurus'; + + declare global { + interface NodeModule { + hot?: {accept: () => void}; + } + } + + // Client-side render (e.g: running in browser) to become single-page + // application (SPA). + if (ExecutionEnvironment.canUseDOM) { + window.docusaurus = docusaurus; + // For production, attempt to hydrate existing markup for performant + // first-load experience. + // For development, there is no existing markup so we had to render it. + // We also preload async component to avoid first-load loading screen. + const renderMethod = + process.env.NODE_ENV === 'production' ? ReactDOM.hydrate : ReactDOM.render; + preload(window.location.pathname).then(() => { + renderMethod( + + + + + , + document.getElementById('__docusaurus'), + ); + }); + + // Webpack Hot Module Replacement API + if (module.hot) { + // Self-accepting method/ trick + // (https://github.com/webpack/webpack-dev-server/issues/100#issuecomment-290911036) + module.hot.accept(); + } + } + \ No newline at end of file From 2ee657bc1e0cce0dba157c8e5f6717a71381e636 Mon Sep 17 00:00:00 2001 From: Sanjaiyan Parthipan Date: Mon, 19 Sep 2022 01:40:27 +0530 Subject: [PATCH 5/8] revert react 18 --- .../docusaurus/src/client/clientEntry.tsx | 89 +++++++++---------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/packages/docusaurus/src/client/clientEntry.tsx b/packages/docusaurus/src/client/clientEntry.tsx index d21e15df1d..8e53d92e10 100644 --- a/packages/docusaurus/src/client/clientEntry.tsx +++ b/packages/docusaurus/src/client/clientEntry.tsx @@ -5,48 +5,47 @@ * LICENSE file in the root directory of this source tree. */ - import React from 'react'; - import ReactDOM from 'react-dom'; - import {BrowserRouter} from 'react-router-dom'; - import {HelmetProvider} from 'react-helmet-async'; - - import ExecutionEnvironment from './exports/ExecutionEnvironment'; - import App from './App'; - import preload from './preload'; - import docusaurus from './docusaurus'; - - declare global { - interface NodeModule { - hot?: {accept: () => void}; - } - } - - // Client-side render (e.g: running in browser) to become single-page - // application (SPA). - if (ExecutionEnvironment.canUseDOM) { - window.docusaurus = docusaurus; - // For production, attempt to hydrate existing markup for performant - // first-load experience. - // For development, there is no existing markup so we had to render it. - // We also preload async component to avoid first-load loading screen. - const renderMethod = - process.env.NODE_ENV === 'production' ? ReactDOM.hydrate : ReactDOM.render; - preload(window.location.pathname).then(() => { - renderMethod( - - - - - , - document.getElementById('__docusaurus'), - ); - }); - - // Webpack Hot Module Replacement API - if (module.hot) { - // Self-accepting method/ trick - // (https://github.com/webpack/webpack-dev-server/issues/100#issuecomment-290911036) - module.hot.accept(); - } - } - \ No newline at end of file +import React from 'react'; +import ReactDOM from 'react-dom'; +import {BrowserRouter} from 'react-router-dom'; +import {HelmetProvider} from 'react-helmet-async'; + +import ExecutionEnvironment from './exports/ExecutionEnvironment'; +import App from './App'; +import preload from './preload'; +import docusaurus from './docusaurus'; + +declare global { + interface NodeModule { + hot?: {accept: () => void}; + } +} + +// Client-side render (e.g: running in browser) to become single-page +// application (SPA). +if (ExecutionEnvironment.canUseDOM) { + window.docusaurus = docusaurus; + // For production, attempt to hydrate existing markup for performant + // first-load experience. + // For development, there is no existing markup so we had to render it. + // We also preload async component to avoid first-load loading screen. + const renderMethod = + process.env.NODE_ENV === 'production' ? ReactDOM.hydrate : ReactDOM.render; + preload(window.location.pathname).then(() => { + renderMethod( + + + + + , + document.getElementById('__docusaurus'), + ); + }); + + // Webpack Hot Module Replacement API + if (module.hot) { + // Self-accepting method/ trick + // (https://github.com/webpack/webpack-dev-server/issues/100#issuecomment-290911036) + module.hot.accept(); + } +} From a077afa577815a84ae88ef369b14a210b4055eba Mon Sep 17 00:00:00 2001 From: Sanjaiyan Parthipan Date: Mon, 19 Sep 2022 01:50:44 +0530 Subject: [PATCH 6/8] fix --- packages/docusaurus/src/client/exports/RouteAnnouncer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx b/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx index c722112735..68ecc66943 100644 --- a/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx +++ b/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx @@ -31,7 +31,7 @@ export const RouteAnnouncer = React.memo(() => { setRouteAnnouncement(content || pathname); } - }, [asPath]); + }, [pathname]); return (

Date: Mon, 19 Sep 2022 02:14:27 +0530 Subject: [PATCH 7/8] add to theme classic --- .../src/theme/RouteAnnouncer/index.tsx} | 18 +++--------------- .../src/theme/RouteAnnouncer/styles.module.css | 12 ++++++++++++ packages/docusaurus/src/client/App.tsx | 2 -- 3 files changed, 15 insertions(+), 17 deletions(-) rename packages/{docusaurus/src/client/exports/RouteAnnouncer.tsx => docusaurus-theme-classic/src/theme/RouteAnnouncer/index.tsx} (67%) create mode 100644 packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css diff --git a/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx b/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/index.tsx similarity index 67% rename from packages/docusaurus/src/client/exports/RouteAnnouncer.tsx rename to packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/index.tsx index 68ecc66943..8133dc7b37 100644 --- a/packages/docusaurus/src/client/exports/RouteAnnouncer.tsx +++ b/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/index.tsx @@ -1,20 +1,8 @@ import React from "react"; import {useLocation} from "@docusaurus/router"; +import styles from './styles.module.css'; -const docusaurusjsRouteAnnouncerStyles: React.CSSProperties = { - border: 0, - clip: "rect(0 0 0 0)", - height: "1px", - margin: "-1px", - overflow: "hidden", - padding: 0, - position: "absolute", - width: "1px", - whiteSpace: "nowrap", - wordWrap: "normal", -}; - -export const RouteAnnouncer = React.memo(() => { +const RouteAnnouncer = React.memo(() => { const { pathname } = useLocation(); const [routeAnnouncement, setRouteAnnouncement] = React.useState(""); const previouslyLoadedPath = React.useRef(pathname); @@ -38,7 +26,7 @@ export const RouteAnnouncer = React.memo(() => { aria-live="assertive" id="__docusaurus-route-announcer__" role="alert" - style={docusaurusjsRouteAnnouncerStyles} + style={styles.docusaurusjsRouteAnnouncerStyles} > {routeAnnouncement}

diff --git a/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css b/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css new file mode 100644 index 0000000000..2e823567ee --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css @@ -0,0 +1,12 @@ +.docusaurusjsRouteAnnouncerStyles { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + white-space: nowrap; + word-wrap: normal; +} \ No newline at end of file diff --git a/packages/docusaurus/src/client/App.tsx b/packages/docusaurus/src/client/App.tsx index 76482d7c41..8554f5b91a 100644 --- a/packages/docusaurus/src/client/App.tsx +++ b/packages/docusaurus/src/client/App.tsx @@ -19,7 +19,6 @@ import {DocusaurusContextProvider} from './docusaurusContext'; import PendingNavigation from './PendingNavigation'; import BaseUrlIssueBanner from './BaseUrlIssueBanner'; import SiteMetadataDefaults from './SiteMetadataDefaults'; -import RouteAnnouncer from './exports/RouteAnnouncer'; // TODO, quick fix for CSS insertion order // eslint-disable-next-line import/order @@ -39,7 +38,6 @@ export default function App(): JSX.Element { {routeElement} - From ce9c5550b14deb0096099896e80287bc70f8de66 Mon Sep 17 00:00:00 2001 From: Sanjaiyan Parthipan Date: Mon, 19 Sep 2022 02:15:26 +0530 Subject: [PATCH 8/8] Update styles.module.css end line --- .../src/theme/RouteAnnouncer/styles.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css b/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css index 2e823567ee..90e500df29 100644 --- a/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/RouteAnnouncer/styles.module.css @@ -9,4 +9,4 @@ width: 1px; white-space: nowrap; word-wrap: normal; -} \ No newline at end of file +}