Представляем Bundle Renderer
Проблемы с обычным SSR
До этого момента мы предполагали, что сборка с кодом серверной части будет напрямую использоваться сервером через require
:
const createApp = require('/path/to/built-server-bundle.js')
Выглядит просто, однако всякий раз, когда вы редактируете исходный код вашего приложения, вам понадобится остановить и перезапустить сервер. Это очень плохо влияет на производительность во время разработки. К тому же, Node.js не поддерживает source maps нативно.
Добавляем BundleRenderer
vue-server-renderer
предоставляет API, названное createBundleRenderer
для решения этой проблемы. С помощью Webpack-плагина, серверная сборка создаётся как специальный JSON-файл, который может быть передан в рендерер. Как только рендерер создан, использование не будет отличаться от обычного рендерера, но появятся некоторые преимущества:
Встроенная поддержка source map (с помощью
devtool: 'source-map'
в конфигурации Webpack)Горячая перезагрузка в процессе разработки и даже развёртывания (путём простого чтения обновлённого пакета и пересоздания экземпляра рендерера)
Внедрение критического CSS (при использовании
*.vue
файлов): автоматически встраивает CSS, необходимый компонентам во время рендеринга. Подробнее в разделе CSS.Внедрение ресурсов с помощью clientManifest: автоматически добавляет оптимальные директивы preload и prefetch, а также фрагменты кода, необходимые для первоначального рендеринга.
Мы обсудим, как настроить Webpack для генерации необходимых частей для рендерера в следующем разделе, а сейчас давайте предположим, что у нас уже есть всё необходимое, и создадим рендерер:
const { createBundleRenderer } = require('vue-server-renderer')
const renderer = createBundleRenderer(serverBundle, {
runInNewContext: false, // рекомендуется
template, // (опционально) шаблон страницы
clientManifest // (опционально) манифест клиентской сборки
})
// внутри обработчика сервера...
server.get('*', (req, res) => {
const context = { url: req.url }
// Нет необходимости передавать приложение тут, потому что оно автоматически создаётся
// при выполнении сборки. Теперь наш сервер отделён от нашего приложения Vue!
renderer.renderToString(context, (err, html) => {
// обработка ошибок...
res.end(html)
})
})
Когда renderToString
вызывается в рендерере, он автоматически выполнит функцию, экспортируемую сборкой для создания экземпляра приложения (передавая context
в качестве аргумента), а затем рендерит его.
Обратите внимание, что рекомендуется установить опцию runInNewContext
в значение false
или 'once'
. См. справочник API для подробностей.