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 type="module" src="/src/entry-client.ts"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.__INITIAL_STATE__ = '<!--pinia-state-->'
|
window.__INITIAL_STATE__ = '__pinia'
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -13,12 +13,29 @@ const APP_PORT = 1007
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
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 () => {
|
;(async () => {
|
||||||
const app = new Koa()
|
const app = new Koa()
|
||||||
|
|
||||||
const vite = await createViteServer({
|
const vite = await createViteServer({
|
||||||
server: { middlewareMode: true },
|
server: { middlewareMode: true },
|
||||||
appType: 'custom',
|
appType: 'spa',
|
||||||
})
|
})
|
||||||
|
|
||||||
app.use(koaConnect(vite.middlewares))
|
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 { 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('<!--ssr-outlet-->', renderedHtml)
|
||||||
.replace('<!--pinia-state-->', state)
|
.replace('__pinia', renderedPinia)
|
||||||
|
|
||||||
ctx.type = 'text/html'
|
ctx.type = 'text/html'
|
||||||
ctx.body = html
|
ctx.body = html
|
||||||
|
|
|
@ -33,8 +33,8 @@ import manifest from './dist/client/ssr-manifest.json' assert { type: 'json' }
|
||||||
|
|
||||||
const html = template
|
const html = template
|
||||||
.replace('<!--preload-links-->', preloadLinks)
|
.replace('<!--preload-links-->', preloadLinks)
|
||||||
.replace('<!--pinia-state-->', state)
|
|
||||||
.replace('<!--ssr-outlet-->', renderedHtml)
|
.replace('<!--ssr-outlet-->', renderedHtml)
|
||||||
|
.replace('__pinia', state)
|
||||||
|
|
||||||
ctx.type = 'text/html'
|
ctx.type = 'text/html'
|
||||||
ctx.body = html
|
ctx.body = html
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import { createApp } from './main'
|
import { createApp } from './main'
|
||||||
import { createKUNGalgameRouter } from './router'
|
import { createKUNGalgameRouter } from './router'
|
||||||
import { setupPinia } from './store'
|
import { setupPinia } from './store'
|
||||||
|
import i18n from '@/language/i18n'
|
||||||
import '@/styles/index.scss'
|
import '@/styles/index.scss'
|
||||||
|
|
||||||
|
const router = createKUNGalgameRouter('client')
|
||||||
|
const pinia = setupPinia()
|
||||||
|
|
||||||
const { app } = createApp()
|
const { app } = createApp()
|
||||||
|
|
||||||
const router = createKUNGalgameRouter()
|
app.use(router).use(pinia).use(i18n)
|
||||||
const pinia = setupPinia()
|
|
||||||
|
|
||||||
if (window.__INITIAL_STATE__) {
|
if (window.__pinia) {
|
||||||
pinia.state.value = JSON.parse(window.__INITIAL_STATE__)
|
pinia.state.value = JSON.parse(window.__pinia)
|
||||||
}
|
}
|
||||||
|
|
||||||
router.isReady().then(() => {
|
router.isReady().then(() => {
|
||||||
|
|
|
@ -13,8 +13,6 @@ import '@/styles/index.scss'
|
||||||
const renderPreloadLink = (file: string) => {
|
const renderPreloadLink = (file: string) => {
|
||||||
if (file.endsWith('.js')) {
|
if (file.endsWith('.js')) {
|
||||||
return `<link rel="modulepreload" crossorigin href="${file}">`
|
return `<link rel="modulepreload" crossorigin href="${file}">`
|
||||||
} else if (file.endsWith('.js')) {
|
|
||||||
return `<link rel="modulepreload" crossorigin href="${file}">`
|
|
||||||
} else if (file.endsWith('.css')) {
|
} else if (file.endsWith('.css')) {
|
||||||
return `<link rel="stylesheet" href="${file}">`
|
return `<link rel="stylesheet" href="${file}">`
|
||||||
} else if (file.endsWith('.png')) {
|
} else if (file.endsWith('.png')) {
|
||||||
|
@ -49,11 +47,11 @@ const renderPreloadLinks = (
|
||||||
export const render = async (
|
export const render = async (
|
||||||
ctx: ParameterizedContext,
|
ctx: ParameterizedContext,
|
||||||
manifest: Record<string, string[]>
|
manifest: Record<string, string[]>
|
||||||
): Promise<[string, string, string]> => {
|
): Promise<[string, string, string, string]> => {
|
||||||
const { app } = createApp()
|
const { app } = createApp()
|
||||||
|
|
||||||
// router
|
// router
|
||||||
const router = createKUNGalgameRouter()
|
const router = createKUNGalgameRouter('server')
|
||||||
app.use(router)
|
app.use(router)
|
||||||
await router.push(ctx.path)
|
await router.push(ctx.path)
|
||||||
await router.isReady()
|
await router.isReady()
|
||||||
|
@ -61,7 +59,8 @@ export const render = async (
|
||||||
// pinia
|
// pinia
|
||||||
const pinia = setupPinia()
|
const pinia = setupPinia()
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
const state = JSON.stringify(pinia.state.value)
|
|
||||||
|
const renderedPinia = JSON.stringify(pinia.state.value)
|
||||||
|
|
||||||
// i18n
|
// i18n
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
|
@ -70,7 +69,9 @@ export const render = async (
|
||||||
|
|
||||||
const renderedHtml = await renderToString(app, renderCtx)
|
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 { constantRoutes } from './router'
|
||||||
import { asyncRoutes } from './router'
|
import { asyncRoutes } from './router'
|
||||||
|
|
||||||
export const createKUNGalgameRouter = (): Router =>
|
export const createKUNGalgameRouter = (type: 'client' | 'server'): Router =>
|
||||||
createRouter({
|
createRouter({
|
||||||
history: import.meta.env.SSR
|
history:
|
||||||
|
type === 'server'
|
||||||
? createMemoryHistory(import.meta.env.BASE_URL)
|
? createMemoryHistory(import.meta.env.BASE_URL)
|
||||||
: createWebHistory(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 {
|
interface Window {
|
||||||
__INITIAL_STATE__: string;
|
__pinia: string
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue