use suspense
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
"react": "^18.0.0-rc.0",
|
"react": "^18.0.0-rc.0",
|
||||||
"react-dom": "^18.0.0-rc.0",
|
"react-dom": "^18.0.0-rc.0",
|
||||||
"react-head": "^3.4.0",
|
"react-head": "^3.4.0",
|
||||||
|
"react-router": "^6.2.1",
|
||||||
"react-router-dom": "^6.2.1"
|
"react-router-dom": "^6.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -28,7 +29,6 @@
|
|||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"esno": "^0.13.0",
|
"esno": "^0.13.0",
|
||||||
"postcss": "^8.4.5",
|
"postcss": "^8.4.5",
|
||||||
"react-location": "^3.3.0",
|
|
||||||
"rehype-highlight": "^5.0.2",
|
"rehype-highlight": "^5.0.2",
|
||||||
"remark-frontmatter": "^4.0.1",
|
"remark-frontmatter": "^4.0.1",
|
||||||
"tailwindcss": "^3.0.8",
|
"tailwindcss": "^3.0.8",
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { description } from "reacord/package.json"
|
import { description } from "reacord/package.json"
|
||||||
|
import { lazy, Suspense } from "react"
|
||||||
import { Meta, Title } from "react-head"
|
import { Meta, Title } from "react-head"
|
||||||
import type { ReactLocation } from "react-location"
|
import { Link, Route, Routes } from "react-router-dom"
|
||||||
import { Link, Outlet, Router } from "react-location"
|
import { lazyNamed } from "./helpers/lazy-named"
|
||||||
import { routes } from "./routes"
|
|
||||||
|
|
||||||
export function App({ location }: { location: ReactLocation }) {
|
export function App() {
|
||||||
return (
|
return (
|
||||||
<Router location={location} routes={routes}>
|
<>
|
||||||
<Title>Reacord</Title>
|
<Title>Reacord</Title>
|
||||||
<Meta name="description" content={description} />
|
<Meta name="description" content={description} />
|
||||||
<nav>
|
<nav>
|
||||||
@@ -14,7 +14,36 @@ export function App({ location }: { location: ReactLocation }) {
|
|||||||
<Link to="docs/getting-started">Getting Started</Link>{" "}
|
<Link to="docs/getting-started">Getting Started</Link>{" "}
|
||||||
<Link to="docs/api">API Reference</Link>
|
<Link to="docs/api">API Reference</Link>
|
||||||
</nav>
|
</nav>
|
||||||
<Outlet />
|
<Suspense fallback={<></>}>
|
||||||
</Router>
|
<Routes>
|
||||||
|
<Route path="/" element={<LandingPage />} />
|
||||||
|
<Route path="docs" element={<DocumentPageLayout />}>
|
||||||
|
{docs.map(({ route, component: Component }) => (
|
||||||
|
<Route key={route} path={route} element={<Component />} />
|
||||||
|
))}
|
||||||
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
</Suspense>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LandingPage = lazyNamed(
|
||||||
|
"LandingPage",
|
||||||
|
() => import("./pages/landing-page"),
|
||||||
|
)
|
||||||
|
|
||||||
|
const DocumentPageLayout = lazyNamed(
|
||||||
|
"DocumentPage",
|
||||||
|
() => import("./pages/document-page"),
|
||||||
|
)
|
||||||
|
|
||||||
|
const docs = Object.entries(import.meta.glob("./docs/*.md")).map(
|
||||||
|
([path, loadModule]) => ({
|
||||||
|
route: path.replace("./docs/", "").replace(/\.md$/, ""),
|
||||||
|
component: lazy(async () => {
|
||||||
|
const m = await loadModule()
|
||||||
|
return { default: m.default || m }
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { createRoot } from "react-dom"
|
import { createRoot } from "react-dom"
|
||||||
import { HeadProvider } from "react-head"
|
import { HeadProvider } from "react-head"
|
||||||
import { ReactLocation } from "react-location"
|
import { BrowserRouter } from "react-router-dom"
|
||||||
import { App } from "./app"
|
import { App } from "./app"
|
||||||
|
|
||||||
const location = new ReactLocation()
|
|
||||||
|
|
||||||
createRoot(document.querySelector("#app")!).render(
|
createRoot(document.querySelector("#app")!).render(
|
||||||
|
<BrowserRouter>
|
||||||
<HeadProvider>
|
<HeadProvider>
|
||||||
<App location={location} />
|
<App />
|
||||||
</HeadProvider>,
|
</HeadProvider>
|
||||||
|
</BrowserRouter>,
|
||||||
)
|
)
|
||||||
|
|
||||||
declare module "react-dom" {
|
declare module "react-dom" {
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import { renderToString } from "react-dom/server"
|
import { renderToString } from "react-dom/server"
|
||||||
import { HeadProvider } from "react-head"
|
import { HeadProvider } from "react-head"
|
||||||
import { createMemoryHistory, ReactLocation } from "react-location"
|
import { StaticRouter } from "react-router-dom/server"
|
||||||
import { App } from "./app"
|
import { App } from "./app"
|
||||||
|
|
||||||
export async function render(url: string) {
|
export async function render(url: string) {
|
||||||
const headTags: React.ReactElement[] = []
|
const headTags: React.ReactElement[] = []
|
||||||
|
|
||||||
const location = new ReactLocation({
|
const app = (
|
||||||
history: createMemoryHistory({ initialEntries: [url] }),
|
<StaticRouter location={url}>
|
||||||
})
|
|
||||||
|
|
||||||
const app = renderToString(
|
|
||||||
<HeadProvider headTags={headTags}>
|
<HeadProvider headTags={headTags}>
|
||||||
<App location={location} />
|
<App />
|
||||||
</HeadProvider>,
|
</HeadProvider>
|
||||||
|
</StaticRouter>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const appHtml = renderToString(app)
|
||||||
|
|
||||||
const scriptSource = import.meta.env.PROD
|
const scriptSource = import.meta.env.PROD
|
||||||
? "/entry.client.js"
|
? "/entry.client.js"
|
||||||
: "/src/entry.client.tsx"
|
: "/src/entry.client.tsx"
|
||||||
@@ -36,7 +36,7 @@ export async function render(url: string) {
|
|||||||
<script type="module" src="${scriptSource}"></script>
|
<script type="module" src="${scriptSource}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app" style="display: contents">${app}</div>
|
<div id="app" style="display: contents">${appHtml}</div>
|
||||||
</body>
|
</body>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|||||||
11
packages/docs-new/src/helpers/lazy-named.ts
Normal file
11
packages/docs-new/src/helpers/lazy-named.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { lazy } from "react"
|
||||||
|
|
||||||
|
export function lazyNamed<
|
||||||
|
Key extends string,
|
||||||
|
Component extends React.ComponentType,
|
||||||
|
>(key: Key, loadModule: () => Promise<Record<Key, Component>>) {
|
||||||
|
return lazy<Component>(async () => {
|
||||||
|
const mod = await loadModule()
|
||||||
|
return { default: mod[key] }
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
import { Outlet } from "react-location"
|
import { Suspense } from "react"
|
||||||
|
import { Outlet } from "react-router"
|
||||||
|
|
||||||
export function DocumentPage() {
|
export function DocumentPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Docs</h1>
|
<h1>Docs</h1>
|
||||||
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
import type { Route } from "react-location"
|
|
||||||
|
|
||||||
export const routes: Route[] = [
|
|
||||||
{
|
|
||||||
path: "/",
|
|
||||||
element: () =>
|
|
||||||
import("./pages/landing-page").then((m) => <m.LandingPage />),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "docs",
|
|
||||||
element: () =>
|
|
||||||
import("./pages/document-page").then((m) => <m.DocumentPage />),
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: "*",
|
|
||||||
element: ({ params }) =>
|
|
||||||
import(`./docs/${params["*"]}.md`).then((m) => <m.default />),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
54
pnpm-lock.yaml
generated
54
pnpm-lock.yaml
generated
@@ -129,7 +129,7 @@ importers:
|
|||||||
react: ^18.0.0-rc.0
|
react: ^18.0.0-rc.0
|
||||||
react-dom: ^18.0.0-rc.0
|
react-dom: ^18.0.0-rc.0
|
||||||
react-head: ^3.4.0
|
react-head: ^3.4.0
|
||||||
react-location: ^3.3.0
|
react-router: ^6.2.1
|
||||||
react-router-dom: ^6.2.1
|
react-router-dom: ^6.2.1
|
||||||
rehype-highlight: ^5.0.2
|
rehype-highlight: ^5.0.2
|
||||||
remark-frontmatter: ^4.0.1
|
remark-frontmatter: ^4.0.1
|
||||||
@@ -143,6 +143,7 @@ importers:
|
|||||||
react: 18.0.0-rc.0
|
react: 18.0.0-rc.0
|
||||||
react-dom: 18.0.0-rc.0_react@18.0.0-rc.0
|
react-dom: 18.0.0-rc.0_react@18.0.0-rc.0
|
||||||
react-head: 3.4.0_757a802188413a36d4f24237d13b8e90
|
react-head: 3.4.0_757a802188413a36d4f24237d13b8e90
|
||||||
|
react-router: 6.2.1_react@18.0.0-rc.0
|
||||||
react-router-dom: 6.2.1_757a802188413a36d4f24237d13b8e90
|
react-router-dom: 6.2.1_757a802188413a36d4f24237d13b8e90
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@mapbox/rehype-prism': 0.8.0
|
'@mapbox/rehype-prism': 0.8.0
|
||||||
@@ -157,7 +158,6 @@ importers:
|
|||||||
compression: 1.7.4
|
compression: 1.7.4
|
||||||
esno: 0.13.0_typescript@4.5.4
|
esno: 0.13.0_typescript@4.5.4
|
||||||
postcss: 8.4.5
|
postcss: 8.4.5
|
||||||
react-location: 3.3.0_757a802188413a36d4f24237d13b8e90
|
|
||||||
rehype-highlight: 5.0.2
|
rehype-highlight: 5.0.2
|
||||||
remark-frontmatter: 4.0.1
|
remark-frontmatter: 4.0.1
|
||||||
tailwindcss: 3.0.8_cefe482e8d38053bbf3d5815e0c551b3
|
tailwindcss: 3.0.8_cefe482e8d38053bbf3d5815e0c551b3
|
||||||
@@ -2171,12 +2171,6 @@ packages:
|
|||||||
babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.5
|
babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.5
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/babylon/7.0.0-beta.47:
|
|
||||||
resolution: {integrity: sha512-+rq2cr4GDhtToEzKFD6KZZMDBXhjFAr9JjPw9pAppZACeEWqNM294j+NdBzkSHYXwzzBmVjZ3nEVJlOhbR2gOQ==}
|
|
||||||
engines: {node: '>=6.0.0'}
|
|
||||||
hasBin: true
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/bail/2.0.2:
|
/bail/2.0.2:
|
||||||
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
|
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
|
||||||
|
|
||||||
@@ -2928,11 +2922,6 @@ packages:
|
|||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/core-js/3.20.1:
|
|
||||||
resolution: {integrity: sha512-btdpStYFQScnNVQ5slVcr858KP0YWYjV16eGJQw8Gg7CWtu/2qNvIM3qVRIR3n1pK2R9NNOrTevbvAYxajwEjg==}
|
|
||||||
requiresBuild: true
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/core-util-is/1.0.3:
|
/core-util-is/1.0.3:
|
||||||
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -4208,16 +4197,6 @@ packages:
|
|||||||
to-regex: 3.0.2
|
to-regex: 3.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/fast-async/7.0.6:
|
|
||||||
resolution: {integrity: sha512-/iUa3eSQC+Xh5tN6QcVLsEsN7b1DaPIoTZo++VpLLIxtdNW2tEmMZex4TcrMeRnBwMOpZwue2CB171wjt5Kgqg==}
|
|
||||||
dependencies:
|
|
||||||
'@babel/generator': 7.16.5
|
|
||||||
'@babel/helper-module-imports': 7.16.7
|
|
||||||
babylon: 7.0.0-beta.47
|
|
||||||
nodent-runtime: 3.2.1
|
|
||||||
nodent-transform: 3.2.9
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/fast-deep-equal/3.1.3:
|
/fast-deep-equal/3.1.3:
|
||||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -4914,6 +4893,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==}
|
resolution: {integrity: sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.16.5
|
'@babel/runtime': 7.16.5
|
||||||
|
dev: false
|
||||||
|
|
||||||
/homedir-polyfill/1.0.3:
|
/homedir-polyfill/1.0.3:
|
||||||
resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==}
|
resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==}
|
||||||
@@ -7300,15 +7280,6 @@ packages:
|
|||||||
update-notifier: 5.1.0
|
update-notifier: 5.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/nodent-runtime/3.2.1:
|
|
||||||
resolution: {integrity: sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA==}
|
|
||||||
requiresBuild: true
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/nodent-transform/3.2.9:
|
|
||||||
resolution: {integrity: sha512-4a5FH4WLi+daH/CGD5o/JWRR8W5tlCkd3nrDSkxbOzscJTyTUITltvOJeQjg3HJ1YgEuNyiPhQbvbtRjkQBByQ==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/nopt/1.0.10:
|
/nopt/1.0.10:
|
||||||
resolution: {integrity: sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=}
|
resolution: {integrity: sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -8204,21 +8175,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/react-location/3.3.0_757a802188413a36d4f24237d13b8e90:
|
|
||||||
resolution: {integrity: sha512-0ME2sVcldYcTGB4DxbD+00wuXHY9NeACjhub3+MKOsBxnTSMQ5P2XWZZwql5IyL9Fj9IL1CjdUnoT4hCL1bCCQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16'
|
|
||||||
react-dom: '>=16'
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.16.5
|
|
||||||
core-js: 3.20.1
|
|
||||||
fast-async: 7.0.6
|
|
||||||
history: 5.2.0
|
|
||||||
react: 18.0.0-rc.0
|
|
||||||
react-dom: 18.0.0-rc.0_react@18.0.0-rc.0
|
|
||||||
ts-toolbelt: 9.6.0
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/react-reconciler/0.26.2_react@17.0.2:
|
/react-reconciler/0.26.2_react@17.0.2:
|
||||||
resolution: {integrity: sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==}
|
resolution: {integrity: sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -9548,10 +9504,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==}
|
resolution: {integrity: sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ts-toolbelt/9.6.0:
|
|
||||||
resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/tsconfig-paths/3.12.0:
|
/tsconfig-paths/3.12.0:
|
||||||
resolution: {integrity: sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==}
|
resolution: {integrity: sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user