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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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