SSR во Vue: createSSRApp, ограничения

↑ 7.5 SSR и Nuxt · ← Предыдущая · → Следующая

Желательно~4 мин чтенияУровень: senior

Зачем это на собесе

Показывает понимание, что происходит «под капотом» Nuxt.

Схема

Один код приложения запускается на сервере и в браузере. Фабрика приложения создаёт новый экземпляр на каждый запрос.

// app.ts (общий)
import { createSSRApp } from 'vue'
import { createRouter, createMemoryHistory, createWebHistory } from 'vue-router'
import { createPinia } from 'pinia'
 
export function createApp() {
  const app = createSSRApp(App)
  const pinia = createPinia()
  const router = createRouter({
    history: import.meta.env.SSR ? createMemoryHistory() : createWebHistory(),
    routes,
  })
  app.use(pinia).use(router)
  return { app, router, pinia }
}
// entry-server.ts
import { renderToString } from 'vue/server-renderer'
export async function render(url: string) {
  const { app, router, pinia } = createApp()
  await router.push(url)
  await router.isReady()
  const html = await renderToString(app)
  return { html, state: pinia.state.value }
}
// entry-client.ts
const { app, router, pinia } = createApp()
pinia.state.value = window.__INITIAL_STATE__
router.isReady().then(() => app.mount('#app'))   // гидрация

Ограничения

  • нет window, document, localStorage на сервере;
  • не хранить состояние в модульных переменных — оно общее для всех запросов (утечка данных между пользователями). Создавать на каждый запрос;
  • хуки mounted, updated и watch с побочными эффектами не выполняются на сервере: только setup, beforeCreate, created;
  • сторонние библиотеки, обращающиеся к DOM при импорте;
  • директивы: для SSR нужны серверные реализации (getSSRProps);
  • утечки памяти: на сервере нет размонтирования, подписки в setup не очищаются.

Инструменты

vite-plugin-ssr / Vike, Nuxt, Quasar SSR, @vue/server-renderer (renderToString, renderToNodeStream, renderToWebStream).

Вопросы с ответами