This commit is contained in:
KUN1007 2023-11-05 15:13:40 +08:00
parent a4a8dc9f0d
commit 627cefaab6
7 changed files with 48 additions and 22 deletions

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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(() => {

View file

@ -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]
}

View file

@ -3,11 +3,12 @@ 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
? createMemoryHistory(import.meta.env.BASE_URL)
: createWebHistory(import.meta.env.BASE_URL),
history:
type === 'server'
? createMemoryHistory(import.meta.env.BASE_URL)
: createWebHistory(import.meta.env.BASE_URL),
routes: [...constantRoutes, ...asyncRoutes] as RouteRecordRaw[],

View file

@ -1,3 +1,3 @@
interface Window {
__INITIAL_STATE__: string;
__pinia: string
}