@fastify/react 0.1.0 → 0.2.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -88
- package/index.js +5 -5
- package/package.json +24 -21
- package/plugin.cjs +2 -7
- package/server/context.js +0 -1
- package/server/stream.js +1 -2
- package/virtual/core.jsx +10 -38
- package/virtual/create.jsx +1 -1
- package/virtual/layouts.js +1 -1
- package/virtual/mount.js +3 -3
- package/virtual/resource.js +0 -1
- package/virtual/root.jsx +4 -4
- package/virtual/context.ts +0 -4
- package/virtual/create.tsx +0 -7
- package/virtual/mount.ts +0 -47
- package/virtual/root.tsx +0 -27
package/README.md
CHANGED
|
@@ -1,90 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
<br>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- [**Quick Start**](https://github.com/fastify/fastify-dx/blob/main/packages/fastify-dx-react/README.md#quick-start)
|
|
5
|
-
- [**Package Scripts**](https://github.com/fastify/fastify-dx/blob/main/packages/fastify-dx-react/README.md#package-scripts)
|
|
6
|
-
- [**Basic Setup**](https://github.com/fastify/fastify-dx/blob/main/docs/react/basic-setup.md)
|
|
7
|
-
- [**Project Structure**](https://github.com/fastify/fastify-dx/blob/main/docs/react/project-structure.md)
|
|
8
|
-
- [**Rendering Modes**](https://github.com/fastify/fastify-dx/blob/main/docs/react/rendering-modes.md)
|
|
9
|
-
- [**Routing Configuration**](https://github.com/fastify/fastify-dx/blob/main/docs/react/routing-config.md)
|
|
10
|
-
- [**Data Prefetching**](https://github.com/fastify/fastify-dx/blob/main/docs/react/data-prefetching.md)
|
|
11
|
-
- [**Route Layouts**](https://github.com/fastify/fastify-dx/blob/main/docs/react/route-layouts.md)
|
|
12
|
-
- [**Route Context**](https://github.com/fastify/fastify-dx/blob/main/docs/react/route-context.md)
|
|
13
|
-
- [**Route Enter Event**](https://github.com/fastify/fastify-dx/blob/main/docs/react/route-enter.md)
|
|
14
|
-
- [**Virtual Modules**](https://github.com/fastify/fastify-dx/blob/main/docs/react/virtual-modules.md)
|
|
3
|
+
**`@fastify/react`** is the official [**`@fastify/vite`**](https://fastify-vite.dev) renderer for React.
|
|
15
4
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
**Fastify DX for React** is a renderer adapter for [**fastify-vite**](https://github.com/fastify/fastify-vite).
|
|
19
|
-
|
|
20
|
-
It is a **fast**, **lightweight** alternative to Next.js and Remix packed with **Developer Experience** features.
|
|
21
|
-
|
|
22
|
-
It has an extremely small core (~1k LOC total) and is built on top of [Fastify](https://github.com/fastify/fastify), [Vite](https://vitejs.dev/), [React Router](https://reactrouter.com/docs/en/v6) and [Valtio](https://github.com/pmndrs/valtio).
|
|
23
|
-
|
|
24
|
-
[**See the release notes for the 0.0.1 alpha release**](https://github.com/fastify/fastify-dx/releases/tag/v0.0.1).
|
|
25
|
-
|
|
26
|
-
> At this stage this project is mostly a [**one-man show**](https://github.com/sponsors/galvez), who's devoting all his free time to its completion. Contributions are extremely welcome, as well as bug reports for any issues you may find.
|
|
27
|
-
|
|
28
|
-
In this first alpha release it's still missing a test suite. The same is true for [**fastify-vite**]().
|
|
29
|
-
|
|
30
|
-
It'll move into **beta** status when test suites are added to both packages.
|
|
31
|
-
|
|
32
|
-
## Quick Start
|
|
33
|
-
|
|
34
|
-
Ensure you have **Node v16+**.
|
|
35
|
-
|
|
36
|
-
Make a copy of [**starters/react**](https://github.com/fastify/fastify-dx/tree/dev/starters/react). If you have [`degit`](https://github.com/Rich-Harris/degit), run the following from a new directory:
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
degit fastify/fastify-dx/starters/react
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
> **If you're starting a project from scratch**, you'll need these packages installed.
|
|
43
|
-
>
|
|
44
|
-
> ```bash
|
|
45
|
-
> npm i fastify fastify-vite fastify-dx-react -P
|
|
46
|
-
> npm i @vitejs/plugin-react -D
|
|
47
|
-
> ```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Run `npm install`.
|
|
51
|
-
|
|
52
|
-
Run `npm run dev`.
|
|
53
|
-
|
|
54
|
-
Visit `http://localhost:3000/`.
|
|
55
|
-
|
|
56
|
-
## What's Included
|
|
57
|
-
|
|
58
|
-
That will get you a **starter template** with:
|
|
59
|
-
|
|
60
|
-
- A minimal [Fastify](https://github.com/fastify/fastify) server.
|
|
61
|
-
- Some dummy API routes.
|
|
62
|
-
- A `pages/` folder with some [demo routes](https://github.com/fastify/fastify-dx/tree/dev/starters/react/client/pages).
|
|
63
|
-
- All configuration files.
|
|
64
|
-
|
|
65
|
-
It also includes some _**opinionated**_ essentials:
|
|
66
|
-
|
|
67
|
-
- [**PostCSS Preset Env**](https://www.npmjs.com/package/postcss-preset-env) by [**Jonathan Neal**](https://github.com/jonathantneal), which enables [several modern CSS features](https://preset-env.cssdb.org/), such as [**CSS Nesting**](https://www.w3.org/TR/css-nesting-1/).
|
|
68
|
-
|
|
69
|
-
- [**UnoCSS**](https://github.com/unocss/unocss) by [**Anthony Fu**](https://antfu.me/), which supports all [Tailwind utilities](https://uno.antfu.me/) and many other goodies through its [default preset](https://github.com/unocss/unocss/tree/main/packages/preset-uno).
|
|
70
|
-
|
|
71
|
-
- [**Valtio**](https://github.com/pmndrs/valtio) by [**Daishi Kato**](https://blog.axlight.com/), with a global and SSR-ready store which you can use anywhere.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
## Package Scripts
|
|
75
|
-
|
|
76
|
-
`npm run dev` boots the development server.
|
|
77
|
-
|
|
78
|
-
`npm run build` creates the production bundle.
|
|
79
|
-
|
|
80
|
-
`npm run serve` serves the production bundle.
|
|
81
|
-
|
|
82
|
-
## Meta
|
|
83
|
-
|
|
84
|
-
Created by [Jonas Galvez](https://github.com/sponsors/galvez), **Engineering Manager** and **Open Sourcerer** at [NearForm](https://nearform.com).
|
|
85
|
-
|
|
86
|
-
## Sponsors
|
|
87
|
-
|
|
88
|
-
<a href="https://nearform.com"><img width="200px" src="https://user-images.githubusercontent.com/12291/172310344-594669fd-da4c-466b-a250-a898569dfea3.svg"></a>
|
|
89
|
-
|
|
90
|
-
Also [**Duc-Thien Bui**](https://github.com/aecea) and [**Tom Preston-Werner**](https://github.com/mojombo) [via GitHub Sponsors](https://github.com/sponsors/galvez). _Thank you!_
|
|
5
|
+
See the [documentation suite](https://fastify-vite.dev) to learn more.
|
package/index.js
CHANGED
|
@@ -4,11 +4,11 @@ import { Readable } from 'stream'
|
|
|
4
4
|
// fastify-vite's minimal HTML templating function,
|
|
5
5
|
// which extracts interpolation variables from comments
|
|
6
6
|
// and returns a function with the generated code
|
|
7
|
-
import { createHtmlTemplateFunction } from '@fastify/vite'
|
|
7
|
+
import { createHtmlTemplateFunction } from '@fastify/vite/utils'
|
|
8
8
|
|
|
9
9
|
// Used to safely serialize JavaScript into
|
|
10
10
|
// <script> tags, preventing a few types of attack
|
|
11
|
-
import devalue from 'devalue'
|
|
11
|
+
import * as devalue from 'devalue'
|
|
12
12
|
|
|
13
13
|
// Small SSR-ready library used to generate
|
|
14
14
|
// <title>, <meta> and <link> elements
|
|
@@ -75,10 +75,10 @@ export function createHtmlFunction (source, scope, config) {
|
|
|
75
75
|
...!context.serverOnly && {
|
|
76
76
|
hydration: (
|
|
77
77
|
'<script>\n' +
|
|
78
|
-
`window.route = ${devalue(context.toJSON())}\n` +
|
|
79
|
-
`window.routes = ${devalue(routes.toJSON())}\n` +
|
|
78
|
+
`window.route = ${devalue.uneval(context.toJSON())}\n` +
|
|
79
|
+
`window.routes = ${devalue.uneval(routes.toJSON())}\n` +
|
|
80
80
|
'</script>'
|
|
81
|
-
)
|
|
81
|
+
),
|
|
82
82
|
},
|
|
83
83
|
}),
|
|
84
84
|
}))
|
package/package.json
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"scripts": {
|
|
3
|
-
"lint": "eslint . --ext .js,.jsx --fix"
|
|
4
|
-
},
|
|
5
2
|
"type": "module",
|
|
6
3
|
"main": "index.js",
|
|
7
4
|
"name": "@fastify/react",
|
|
8
|
-
"
|
|
5
|
+
"description": "The official @fastify/vite renderer for React",
|
|
6
|
+
"version": "0.2.0-rc.1",
|
|
9
7
|
"files": [
|
|
10
8
|
"virtual/create.jsx",
|
|
11
9
|
"virtual/create.tsx",
|
|
@@ -31,27 +29,32 @@
|
|
|
31
29
|
"./plugin": "./plugin.cjs"
|
|
32
30
|
},
|
|
33
31
|
"dependencies": {
|
|
34
|
-
"devalue": "
|
|
35
|
-
"history": "
|
|
36
|
-
"minipass": "
|
|
32
|
+
"devalue": "latest",
|
|
33
|
+
"history": "latest",
|
|
34
|
+
"minipass": "latest",
|
|
37
35
|
"react": "^18.2.0",
|
|
38
|
-
"react-dom": "
|
|
39
|
-
"react-router-dom": "
|
|
40
|
-
"unihead": "
|
|
41
|
-
"valtio": "
|
|
36
|
+
"react-dom": "latest",
|
|
37
|
+
"react-router-dom": "latest",
|
|
38
|
+
"unihead": "latest",
|
|
39
|
+
"valtio": "latest"
|
|
42
40
|
},
|
|
43
41
|
"devDependencies": {
|
|
44
|
-
"@babel/eslint-parser": "
|
|
45
|
-
"@babel/preset-react": "
|
|
46
|
-
"
|
|
47
|
-
"eslint": "
|
|
48
|
-
"eslint-
|
|
49
|
-
"eslint-plugin-
|
|
50
|
-
"eslint-plugin-
|
|
51
|
-
"eslint-plugin-
|
|
52
|
-
|
|
42
|
+
"@babel/eslint-parser": "latest",
|
|
43
|
+
"@babel/preset-react": "latest",
|
|
44
|
+
"eslint": "latest",
|
|
45
|
+
"eslint-config-standard": "latest",
|
|
46
|
+
"eslint-plugin-import": "latest",
|
|
47
|
+
"eslint-plugin-node": "latest",
|
|
48
|
+
"eslint-plugin-promise": "latest",
|
|
49
|
+
"eslint-plugin-react": "latest"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@fastify/vite": "^5.0.2"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"lint": "eslint . --ext .js,.jsx --fix"
|
|
56
59
|
}
|
|
57
|
-
}
|
|
60
|
+
}
|
package/plugin.cjs
CHANGED
|
@@ -3,7 +3,7 @@ const { dirname, join, resolve } = require('path')
|
|
|
3
3
|
const { fileURLToPath } = require('url')
|
|
4
4
|
|
|
5
5
|
function viteReactFastifyDX (config = {}) {
|
|
6
|
-
const prefix =
|
|
6
|
+
const prefix = /^\/:/
|
|
7
7
|
const routing = Object.assign({
|
|
8
8
|
globPattern: '/pages/**/*.(jsx|tsx)',
|
|
9
9
|
paramPattern: /\[(\w+)\]/,
|
|
@@ -11,18 +11,13 @@ function viteReactFastifyDX (config = {}) {
|
|
|
11
11
|
const virtualRoot = resolve(__dirname, 'virtual')
|
|
12
12
|
const virtualModules = [
|
|
13
13
|
'mount.js',
|
|
14
|
-
'mount.ts',
|
|
15
14
|
'resource.js',
|
|
16
|
-
'resource.ts',
|
|
17
15
|
'routes.js',
|
|
18
16
|
'layouts.js',
|
|
19
17
|
'create.jsx',
|
|
20
|
-
'create.tsx',
|
|
21
18
|
'root.jsx',
|
|
22
|
-
'root.tsx',
|
|
23
19
|
'layouts/',
|
|
24
20
|
'context.js',
|
|
25
|
-
'context.ts',
|
|
26
21
|
'core.jsx'
|
|
27
22
|
]
|
|
28
23
|
virtualModules.includes = function (virtual) {
|
|
@@ -79,7 +74,7 @@ function viteReactFastifyDX (config = {}) {
|
|
|
79
74
|
}
|
|
80
75
|
|
|
81
76
|
return {
|
|
82
|
-
name: 'vite-plugin-
|
|
77
|
+
name: 'vite-plugin-fastify-react',
|
|
83
78
|
config (config, { command }) {
|
|
84
79
|
if (command === 'build' && config.build?.ssr) {
|
|
85
80
|
config.build.rollupOptions = {
|
package/server/context.js
CHANGED
package/server/stream.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
1
|
// Helper to make the stream returned renderToPipeableStream()
|
|
3
2
|
// behave like an event emitter and facilitate error handling in Fastify
|
|
4
|
-
import Minipass from 'minipass'
|
|
3
|
+
import { Minipass } from 'minipass'
|
|
5
4
|
|
|
6
5
|
// React 18's preferred server-side rendering function,
|
|
7
6
|
// which enables the combination of React.lazy() and Suspense
|
package/virtual/core.jsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createContext, useContext, useEffect } from 'react'
|
|
2
|
-
import { useLocation, BrowserRouter
|
|
2
|
+
import { useLocation, BrowserRouter } from 'react-router-dom'
|
|
3
3
|
import { StaticRouter } from 'react-router-dom/server.mjs'
|
|
4
4
|
import { createPath } from 'history'
|
|
5
5
|
import { proxy, useSnapshot } from 'valtio'
|
|
6
|
-
import { waitResource, waitFetch } from '
|
|
7
|
-
import layouts from '
|
|
6
|
+
import { waitResource, waitFetch } from '/:resource.js'
|
|
7
|
+
import layouts from '/:layouts.js'
|
|
8
8
|
|
|
9
9
|
export const isServer = import.meta.env.SSR
|
|
10
10
|
export const Router = isServer ? StaticRouter : BrowserRouter
|
|
@@ -14,41 +14,13 @@ export function useRouteContext () {
|
|
|
14
14
|
const routeContext = useContext(RouteContext)
|
|
15
15
|
if (routeContext.state) {
|
|
16
16
|
routeContext.snapshot = isServer
|
|
17
|
-
? routeContext.state
|
|
18
|
-
: useSnapshot(routeContext.state)
|
|
17
|
+
? routeContext.state ?? {}
|
|
18
|
+
: useSnapshot(routeContext.state ?? {})
|
|
19
19
|
}
|
|
20
20
|
return routeContext
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export function
|
|
24
|
-
url,
|
|
25
|
-
routes,
|
|
26
|
-
head,
|
|
27
|
-
routeMap,
|
|
28
|
-
ctxHydration,
|
|
29
|
-
}) {
|
|
30
|
-
return (
|
|
31
|
-
<Router location={url}>
|
|
32
|
-
<Routes>{
|
|
33
|
-
routes.map(({ path, component: Component }) =>
|
|
34
|
-
<Route
|
|
35
|
-
key={path}
|
|
36
|
-
path={path}
|
|
37
|
-
element={
|
|
38
|
-
<DXRoute
|
|
39
|
-
head={head}
|
|
40
|
-
ctxHydration={ctxHydration}
|
|
41
|
-
ctx={routeMap[path]}>
|
|
42
|
-
<Component />
|
|
43
|
-
</DXRoute>
|
|
44
|
-
} />,
|
|
45
|
-
)
|
|
46
|
-
}</Routes>
|
|
47
|
-
</Router>
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function DXRoute ({ head, ctxHydration, ctx, children }) {
|
|
23
|
+
export function AppRoute ({ head, ctxHydration, ctx, children }) {
|
|
52
24
|
// If running on the server, assume all data
|
|
53
25
|
// functions have already ran through the preHandler hook
|
|
54
26
|
if (isServer) {
|
|
@@ -58,8 +30,8 @@ export function DXRoute ({ head, ctxHydration, ctx, children }) {
|
|
|
58
30
|
...ctx,
|
|
59
31
|
...ctxHydration,
|
|
60
32
|
state: isServer
|
|
61
|
-
? ctxHydration.state
|
|
62
|
-
: proxy(ctxHydration.state),
|
|
33
|
+
? ctxHydration.state ?? {}
|
|
34
|
+
: proxy(ctxHydration.state ?? {}),
|
|
63
35
|
}}>
|
|
64
36
|
<Layout>
|
|
65
37
|
{children}
|
|
@@ -134,8 +106,8 @@ export function DXRoute ({ head, ctxHydration, ctx, children }) {
|
|
|
134
106
|
...ctxHydration,
|
|
135
107
|
...ctx,
|
|
136
108
|
state: isServer
|
|
137
|
-
? ctxHydration.state
|
|
138
|
-
: proxy(ctxHydration.state),
|
|
109
|
+
? ctxHydration.state ?? {}
|
|
110
|
+
: proxy(ctxHydration.state ?? {}),
|
|
139
111
|
}}>
|
|
140
112
|
<Layout>
|
|
141
113
|
{children}
|
package/virtual/create.jsx
CHANGED
package/virtual/layouts.js
CHANGED
package/virtual/mount.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Head from 'unihead/client'
|
|
2
2
|
import { createRoot, hydrateRoot } from 'react-dom/client'
|
|
3
3
|
|
|
4
|
-
import create from '
|
|
5
|
-
import routesPromise from '
|
|
4
|
+
import create from '/:create.jsx'
|
|
5
|
+
import routesPromise from '/:routes.js'
|
|
6
6
|
|
|
7
7
|
mount('main')
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ async function mount (target) {
|
|
|
10
10
|
if (typeof target === 'string') {
|
|
11
11
|
target = document.querySelector(target)
|
|
12
12
|
}
|
|
13
|
-
const context = await import('
|
|
13
|
+
const context = await import('/:context.js')
|
|
14
14
|
const ctxHydration = await extendContext(window.route, context)
|
|
15
15
|
const head = new Head(window.route.head, window.document)
|
|
16
16
|
const resolvedRoutes = await routesPromise
|
package/virtual/resource.js
CHANGED
package/virtual/root.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Suspense } from 'react'
|
|
2
2
|
import { Routes, Route } from 'react-router-dom'
|
|
3
|
-
import { Router,
|
|
3
|
+
import { Router, AppRoute } from '/:core.jsx'
|
|
4
4
|
|
|
5
5
|
export default function Root ({ url, routes, head, ctxHydration, routeMap }) {
|
|
6
6
|
return (
|
|
@@ -12,16 +12,16 @@ export default function Root ({ url, routes, head, ctxHydration, routeMap }) {
|
|
|
12
12
|
key={path}
|
|
13
13
|
path={path}
|
|
14
14
|
element={
|
|
15
|
-
<
|
|
15
|
+
<AppRoute
|
|
16
16
|
head={head}
|
|
17
17
|
ctxHydration={ctxHydration}
|
|
18
18
|
ctx={routeMap[path]}>
|
|
19
19
|
<Component />
|
|
20
|
-
</
|
|
20
|
+
</AppRoute>
|
|
21
21
|
} />,
|
|
22
22
|
)
|
|
23
23
|
}</Routes>
|
|
24
24
|
</Router>
|
|
25
25
|
</Suspense>
|
|
26
26
|
)
|
|
27
|
-
}
|
|
27
|
+
}
|
package/virtual/context.ts
DELETED
package/virtual/create.tsx
DELETED
package/virtual/mount.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import Head from 'unihead/client'
|
|
2
|
-
import { createRoot, hydrateRoot } from 'react-dom/client'
|
|
3
|
-
|
|
4
|
-
import create from '/dx:create.tsx'
|
|
5
|
-
import routesPromise from '/dx:routes.js'
|
|
6
|
-
|
|
7
|
-
mount('main')
|
|
8
|
-
|
|
9
|
-
async function mount (target) {
|
|
10
|
-
if (typeof target === 'string') {
|
|
11
|
-
target = document.querySelector(target)
|
|
12
|
-
}
|
|
13
|
-
const context = await import('/dx:context.ts')
|
|
14
|
-
const ctxHydration = await extendContext(window.route, context)
|
|
15
|
-
const head = new Head(window.route.head, window.document)
|
|
16
|
-
const resolvedRoutes = await routesPromise
|
|
17
|
-
const routeMap = Object.fromEntries(
|
|
18
|
-
resolvedRoutes.map((route) => [route.path, route]),
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
const app = create({
|
|
22
|
-
head,
|
|
23
|
-
ctxHydration,
|
|
24
|
-
routes: window.routes,
|
|
25
|
-
routeMap,
|
|
26
|
-
})
|
|
27
|
-
if (ctxHydration.clientOnly) {
|
|
28
|
-
createRoot(target).render(app)
|
|
29
|
-
} else {
|
|
30
|
-
hydrateRoot(target, app)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function extendContext (ctx, {
|
|
35
|
-
// The route context initialization function
|
|
36
|
-
default: setter,
|
|
37
|
-
// We destructure state here just to discard it from extra
|
|
38
|
-
state,
|
|
39
|
-
// Other named exports from context.js
|
|
40
|
-
...extra
|
|
41
|
-
}) {
|
|
42
|
-
Object.assign(ctx, extra)
|
|
43
|
-
if (setter) {
|
|
44
|
-
await setter(ctx)
|
|
45
|
-
}
|
|
46
|
-
return ctx
|
|
47
|
-
}
|
package/virtual/root.tsx
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Suspense } from 'react'
|
|
2
|
-
import { Routes, Route } from 'react-router-dom'
|
|
3
|
-
import { Router, DXRoute } from '/dx:core.jsx'
|
|
4
|
-
|
|
5
|
-
export default function Root ({ url, routes, head, ctxHydration, routeMap }) {
|
|
6
|
-
return (
|
|
7
|
-
<Suspense>
|
|
8
|
-
<Router location={url}>
|
|
9
|
-
<Routes>{
|
|
10
|
-
routes.map(({ path, component: Component }) =>
|
|
11
|
-
<Route
|
|
12
|
-
key={path}
|
|
13
|
-
path={path}
|
|
14
|
-
element={
|
|
15
|
-
<DXRoute
|
|
16
|
-
head={head}
|
|
17
|
-
ctxHydration={ctxHydration}
|
|
18
|
-
ctx={routeMap[path]}>
|
|
19
|
-
<Component />
|
|
20
|
-
</DXRoute>
|
|
21
|
-
} />,
|
|
22
|
-
)
|
|
23
|
-
}</Routes>
|
|
24
|
-
</Router>
|
|
25
|
-
</Suspense>
|
|
26
|
-
)
|
|
27
|
-
}
|