test ssr
This commit is contained in:
parent
a4a8dc9f0d
commit
627cefaab6
|
@ -20,7 +20,7 @@
|
|||
<script type="module" src="/src/entry-client.ts"></script>
|
||||
|
||||
<script>
|
||||
window.__INITIAL_STATE__ = '<!--pinia-state-->'
|
||||
window.__INITIAL_STATE__ = '__pinia'
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -13,12 +13,29 @@ const APP_PORT = 1007
|
|||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
// Inject teleports in template
|
||||
const injectTeleports = (html: string, teleports: string) => {
|
||||
if (teleports) {
|
||||
for (const [target, content] of Object.entries(teleports)) {
|
||||
if (['head', 'body', 'html'].includes(target)) {
|
||||
const replacement = `</${target}>`
|
||||
html = html.replace(replacement, content + replacement)
|
||||
} else {
|
||||
const replacement = ` id="${target.replace('#', '')}">`
|
||||
html = html.replace(replacement, replacement + content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return html
|
||||
}
|
||||
|
||||
;(async () => {
|
||||
const app = new Koa()
|
||||
|
||||
const vite = await createViteServer({
|
||||
server: { middlewareMode: true },
|
||||
appType: 'custom',
|
||||
appType: 'spa',
|
||||
})
|
||||
|
||||
app.use(koaConnect(vite.middlewares))
|
||||
|
@ -34,11 +51,15 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|||
|
||||
const { render } = await vite.ssrLoadModule('/src/entry-server.ts')
|
||||
|
||||
const [renderedHtml, state] = await render(ctx, {})
|
||||
const [renderedHtml, renderedPinia, renderedLinks, renderedTeleports] =
|
||||
await render(ctx, {})
|
||||
|
||||
const html = template
|
||||
const injectedTeleportsHtml = injectTeleports(template, renderedTeleports)
|
||||
|
||||
const html = injectedTeleportsHtml
|
||||
.replace('<!--preload-links-->', renderedLinks)
|
||||
.replace('<!--ssr-outlet-->', renderedHtml)
|
||||
.replace('<!--pinia-state-->', state)
|
||||
.replace('__pinia', renderedPinia)
|
||||
|
||||
ctx.type = 'text/html'
|
||||
ctx.body = html
|
||||
|
|
|
@ -33,8 +33,8 @@ import manifest from './dist/client/ssr-manifest.json' assert { type: 'json' }
|
|||
|
||||
const html = template
|
||||
.replace('<!--preload-links-->', preloadLinks)
|
||||
.replace('<!--pinia-state-->', state)
|
||||
.replace('<!--ssr-outlet-->', renderedHtml)
|
||||
.replace('__pinia', state)
|
||||
|
||||
ctx.type = 'text/html'
|
||||
ctx.body = html
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import { createApp } from './main'
|
||||
import { createKUNGalgameRouter } from './router'
|
||||
import { setupPinia } from './store'
|
||||
import i18n from '@/language/i18n'
|
||||
import '@/styles/index.scss'
|
||||
|
||||
const router = createKUNGalgameRouter('client')
|
||||
const pinia = setupPinia()
|
||||
|
||||
const { app } = createApp()
|
||||
|
||||
const router = createKUNGalgameRouter()
|
||||
const pinia = setupPinia()
|
||||
app.use(router).use(pinia).use(i18n)
|
||||
|
||||
if (window.__INITIAL_STATE__) {
|
||||
pinia.state.value = JSON.parse(window.__INITIAL_STATE__)
|
||||
if (window.__pinia) {
|
||||
pinia.state.value = JSON.parse(window.__pinia)
|
||||
}
|
||||
|
||||
router.isReady().then(() => {
|
||||
|
|
|
@ -13,8 +13,6 @@ import '@/styles/index.scss'
|
|||
const renderPreloadLink = (file: string) => {
|
||||
if (file.endsWith('.js')) {
|
||||
return `<link rel="modulepreload" crossorigin href="${file}">`
|
||||
} else if (file.endsWith('.js')) {
|
||||
return `<link rel="modulepreload" crossorigin href="${file}">`
|
||||
} else if (file.endsWith('.css')) {
|
||||
return `<link rel="stylesheet" href="${file}">`
|
||||
} else if (file.endsWith('.png')) {
|
||||
|
@ -49,11 +47,11 @@ const renderPreloadLinks = (
|
|||
export const render = async (
|
||||
ctx: ParameterizedContext,
|
||||
manifest: Record<string, string[]>
|
||||
): Promise<[string, string, string]> => {
|
||||
): Promise<[string, string, string, string]> => {
|
||||
const { app } = createApp()
|
||||
|
||||
// router
|
||||
const router = createKUNGalgameRouter()
|
||||
const router = createKUNGalgameRouter('server')
|
||||
app.use(router)
|
||||
await router.push(ctx.path)
|
||||
await router.isReady()
|
||||
|
@ -61,7 +59,8 @@ export const render = async (
|
|||
// pinia
|
||||
const pinia = setupPinia()
|
||||
app.use(pinia)
|
||||
const state = JSON.stringify(pinia.state.value)
|
||||
|
||||
const renderedPinia = JSON.stringify(pinia.state.value)
|
||||
|
||||
// i18n
|
||||
app.use(i18n)
|
||||
|
@ -70,7 +69,9 @@ export const render = async (
|
|||
|
||||
const renderedHtml = await renderToString(app, renderCtx)
|
||||
|
||||
const preloadLinks = renderPreloadLinks(renderCtx.modules, manifest)
|
||||
const renderedLinks = renderPreloadLinks(renderCtx.modules, manifest)
|
||||
|
||||
return [renderedHtml, state, preloadLinks]
|
||||
const renderedTeleports = ctx.teleports
|
||||
|
||||
return [renderedHtml, renderedPinia, renderedLinks, renderedTeleports]
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ import { createWebHistory, createRouter, createMemoryHistory } from 'vue-router'
|
|||
import { constantRoutes } from './router'
|
||||
import { asyncRoutes } from './router'
|
||||
|
||||
export const createKUNGalgameRouter = (): Router =>
|
||||
export const createKUNGalgameRouter = (type: 'client' | 'server'): Router =>
|
||||
createRouter({
|
||||
history: import.meta.env.SSR
|
||||
history:
|
||||
type === 'server'
|
||||
? createMemoryHistory(import.meta.env.BASE_URL)
|
||||
: createWebHistory(import.meta.env.BASE_URL),
|
||||
|
||||
|
|
2
src/types/shims-global.d.ts
vendored
2
src/types/shims-global.d.ts
vendored
|
@ -1,3 +1,3 @@
|
|||
interface Window {
|
||||
__INITIAL_STATE__: string;
|
||||
__pinia: string
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue