Skip to content

Commit cada9db

Browse files
authored
feat: flag to turn off ssr (#26)
* chore: be able to turn off ssr if needed * chore: remove comments * feat: client first (#25) * feat: move it to be client first instead of server first * fix: builds for islands
1 parent cf6e461 commit cada9db

File tree

16 files changed

+431
-207
lines changed

16 files changed

+431
-207
lines changed

adex/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717
"type": "module",
1818
"exports": {
1919
"./package.json": "./package.json",
20+
"./router": {
21+
"types": "./src/router.d.ts",
22+
"import": "./src/router.js"
23+
},
24+
"./utils/isomorphic": {
25+
"types": "./src/utils/isomorphic.d.ts",
26+
"import": "./src/utils/isomorphic.js"
27+
},
2028
"./ssr": {
2129
"types": "./src/ssr.d.ts",
2230
"import": "./src/ssr.js"
@@ -61,6 +69,7 @@
6169
"hoofd": "^1.7.1",
6270
"mri": "^1.2.0",
6371
"node-stream-zip": "^1.15.0",
72+
"preact-iso": "^2.9.0",
6473
"preact-render-to-string": "^6.5.5",
6574
"regexparam": "^3.0.0",
6675
"sirv": "^2.0.4",

adex/runtime/client.js

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,51 @@
1-
import { hydrate as preactHydrate, h } from 'preact'
1+
import { h } from 'preact'
2+
import {
3+
LocationProvider,
4+
Router,
5+
Route,
6+
lazy,
7+
hydrate as preactHydrate,
8+
ErrorBoundary,
9+
} from 'adex/router'
10+
211
import 'virtual:adex:global.css'
312

4-
const pageRoutes = import.meta.glob('/src/pages/**/*.{tsx,jsx,js}')
13+
// @ts-expect-error injected by vite
14+
import { routes } from '~routes'
515

6-
async function hydrate() {
7-
const entryPage = document.getElementById('app').dataset.entryPage
8-
const routeParams = document.getElementById('app').dataset.routeParams
9-
const componentModule = await pageRoutes[entryPage]()
10-
const Component =
11-
'default' in componentModule ? componentModule.default : componentModule
12-
preactHydrate(
13-
h(Component, {
14-
routeParams: routeParams ? JSON.parse(atob(routeParams)) : {},
15-
}),
16-
document.getElementById('app')
16+
const withComponents = routes.map(d => {
17+
return {
18+
...d,
19+
component: lazy(d.module),
20+
}
21+
})
22+
23+
function ComponentWrapper({ url = '' }) {
24+
return h(
25+
LocationProvider,
26+
//@ts-expect-error no types for non-jsx function
27+
{ url: url },
28+
h(
29+
ErrorBoundary,
30+
{},
31+
h(
32+
Router,
33+
{},
34+
withComponents.map(d =>
35+
h(Route, { path: d.routePath, component: d.component })
36+
)
37+
)
38+
)
1739
)
1840
}
1941

20-
hydrate()
42+
export const App = ({ url = '' }) => {
43+
return h(ComponentWrapper, { url })
44+
}
45+
46+
async function hydrate() {
47+
preactHydrate(h(ComponentWrapper, {}), document.getElementById('app'))
48+
}
49+
if (typeof window !== 'undefined') {
50+
hydrate()
51+
}

adex/runtime/handler.js

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { CONSTANTS, emitToHooked } from 'adex/hook'
22
import { prepareRequest, prepareResponse } from 'adex/http'
3-
import { renderToString, toStatic } from 'adex/ssr'
3+
import { toStatic } from 'adex/ssr'
4+
import { renderToString } from 'adex/utils/isomorphic'
45
import { h } from 'preact'
56

7+
// @ts-expect-error injected by vite
8+
import { App } from 'virtual:adex:client'
9+
610
// @ts-expect-error injected by vite
711
import { routes as apiRoutes } from '~apiRoutes'
812
// @ts-expect-error injected by vite
@@ -16,7 +20,8 @@ export async function handler(req, res) {
1620
prepareRequest(req)
1721
prepareResponse(res)
1822

19-
const [baseURL] = req.url.split('?')
23+
const [url, search] = req.url.split('?')
24+
const baseURL = normalizeRequestUrl(url)
2025

2126
const { metas, links, title, lang } = toStatic()
2227

@@ -50,10 +55,15 @@ export async function handler(req, res) {
5055
})
5156

5257
if (matchedInPages) {
53-
const module = await matchedInPages.module()
54-
const render = 'default' in module ? module.default : module
5558
const routeParams = getRouteParams(baseURL, matchedInPages)
5659

60+
// @ts-expect-error
61+
global.location = new URL(req.url, 'http://localhost')
62+
63+
const rendered = await renderToString(
64+
h(App, { url: [baseURL, search].filter(Boolean).join('?') })
65+
)
66+
5767
const htmlString = HTMLTemplate({
5868
metas,
5969
links,
@@ -63,7 +73,7 @@ export async function handler(req, res) {
6373
routeParams: Buffer.from(JSON.stringify(routeParams), 'utf8').toString(
6474
'base64'
6575
),
66-
body: renderToString(h(render, { routeParams })),
76+
body: rendered.html,
6777
})
6878
const modifiableContext = {
6979
req: req,
@@ -105,13 +115,7 @@ function HTMLTemplate({
105115
${headString}
106116
</head>
107117
<body>
108-
<div
109-
id="app"
110-
data-entry-page="${entryPage}"
111-
data-route-params="${routeParams}"
112-
>
113-
${body}
114-
</div>
118+
<div id="app">${body}</div>
115119
</body>
116120
</html>
117121
`
@@ -146,3 +150,7 @@ const stringify = (title, metas, links) => {
146150
${stringifyTag('link', links)}
147151
`
148152
}
153+
154+
function normalizeRequestUrl(url) {
155+
return url.replace(/\/(index\.html)$/, '/')
156+
}

adex/runtime/pages.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { pathToRegex } from 'adex/ssr'
1+
import { pathToRegex } from 'adex/utils/isomorphic'
22

33
const pages = import.meta.glob('#{__PLUGIN_PAGES_ROOT}')
44

adex/src/fonts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function fonts({ providers = [], families = [] } = {}) {
4949
},
5050
async transform(code, id) {
5151
const resolvedData = await this.resolve('virtual:adex:client')
52-
if (id === resolvedData.id) {
52+
if (resolvedData?.id == id) {
5353
return {
5454
code: `import "${fontVirtualId}";\n` + code,
5555
}

adex/src/router.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export {
2+
hydrate,
3+
Router,
4+
Route,
5+
lazy,
6+
LocationProvider,
7+
ErrorBoundary,
8+
} from 'preact-iso'

adex/src/router.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export {
2+
hydrate,
3+
Router,
4+
ErrorBoundary,
5+
Route,
6+
lazy,
7+
LocationProvider,
8+
} from 'preact-iso'

adex/src/ssr.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
export { toStatic } from 'hoofd/preact'
2-
export { renderToString } from 'preact-render-to-string'
3-
export { parse as pathToRegex } from 'regexparam'
42
export { use as useMiddleware } from '@barelyhuman/tiny-use'
53
export { default as sirv } from 'sirv'
6-
export { default as mri } from 'mri'
4+
export { default as mri } from 'mri'

adex/src/ssr.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
export { renderToString } from 'preact-render-to-string'
1+
export { prerender as renderToString } from 'preact-iso'
22
export { default as sirv } from 'sirv'
33
export { default as mri } from 'mri'
4-
export { parse as pathToRegex } from 'regexparam'
54
export { toStatic } from 'hoofd/preact'
65
export { use as useMiddleware } from '@barelyhuman/tiny-use'

adex/src/utils/isomorphic.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { parse as pathToRegex } from 'regexparam'
2+
export { prerender as renderToString } from 'preact-iso'

0 commit comments

Comments
 (0)