Некоторое время обдумывал идею личного проекта. Закончил использование Vue просто для удовольствия (никаких технических причин для этого выбора). Детали этого проекта скрыты, но самое главное, мне нужно было:
- Управление состоянием
- Создавать динамические маршруты
- Обработка на сервер
SSR (рендеринг на стороне сервера) был моей главной заботой - о состоянии и маршрутизации можно было позаботиться за пару минут.
Самым быстрым путем был плагин предварительного рендеринга Webpack. Но не слишком быстро; Если в вашем приложении много динамических маршрутов, этот плагин может быть не лучшим выбором, потому что он не был для меня
Помимо собственной реализации решения с помощью vue-server-renderer, единственным вариантом, который у меня оставался, был Nuxt.
Nuxt для ленивых
Да, если вы меня встречали, значит, вы знаете, какой я ленивый. Что еще хуже, мой мозг категорически отказывается идти долгим путем к проблемам, когда есть проверенный и надежный ярлык.
Nuxt позволяет вам просто написать приложение Vue с рендерингом на сервере, не ограничиваясь низкоуровневой реализацией. Он был вдохновлен Next, который широко известен в сообществе React как средство решения связанных проблем.
SSR Gotchas
Nuxt звучит настолько интересно, что вы сразу бы сразу к нему применили. К сожалению, в SSR есть некоторые ошибки, и использование таких инструментов, как Nuxt или Next (в зависимости от обстоятельств) не скрывает этих ошибок; вам еще нужно с ними разобраться.
Первое, с чем вы наверняка столкнетесь, - это попытка получить доступ к объектам browser
или document
еще до того, как они будут готовы. Помните, что ваш шаблон сначала отображается на сервере, а не на клиенте. Когда вы пытаетесь получить доступ к этим объектам слишком рано, сервер выдает ошибку, подобную следующей, в зависимости от того, в каком случае:
> window is not defined
Возможно, вы захотите держаться подальше от таких объектов и обращаться к ним только с помощью методов жизненного цикла, таких как mounted
, что гарантирует готовность клиента. Плохая новость в том, что большинство библиотек, которые вы импортируете в свой проект, будут пытаться получить доступ window
или document
до того, как приложение будет отображено в браузере.
На решение этой проблемы у меня ушло несколько часов отладки, поиска в Google, бесконечных открытых вкладок Chrome и поиска проблем с Github.
Это был мой способ обойти это ...
Первая попытка: дождитесь рендеринга браузера
Предполагая, что у вас есть следующая логика компонентов:
// Problem here window.globalVar = 'global variable' export default { mounted() { console.log(window.globalVar); }, }
К сожалению, окно будет неопределенным. Большинство плагинов, таких как vue-select
(которые я использовал), обращаются к объекту окна так рано, как это.
Nuxt предоставляет флаг для объекта process
, который вы можете использовать, чтобы проверить, установлен ли браузер. Вышеуказанная проблема будет легко устранена:
if (process.browser) { window.globalVar = 'global variable' } export default { mounted() { console.log(window.globalVar); }, }
Следовательно, в случаях, когда вы используете плагин, который обращается к объекту окна сразу, как они импортируются, это должно работать:
let pluginLib; if (process.browser) { pluginLib = require('plugin-name'); } export default { mounted() { console.log(pluginLib); }, }
Не забудьте включить плагин в массив vendor сборки:
// nuxt.config.js build: { vendor: ['plugin-name'] }
Это будет работать для вас, пока ваша сторонняя библиотека не станет той, которая должна внедрить шаблон в представление (что и делает большинство библиотек пользовательского интерфейса). В моем случае это был vue-select. По некоторым причинам возникла следующая ошибка:
> You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
Это привело к моей второй попытке.
Вторая попытка: плагины Vue
С подсказками, которые я почерпнул из этой проблемы, я смог написать плагин, который загружается только на клиенте. Сначала создайте плагин в папке plugins
:
import Vue from 'vue' import vSelect from 'vue-select'; const VueSelect = { install(Vue, options) { Vue.component('v-select', vSelect) } }; Vue.use(VueSelect); export default VueSelect;
Затем сообщите Nuxt, что это следует загружать только в браузере, используя свойство ssr
и задав значение false
.
// nuxt.config.js plugins: [ { src: '~plugins/vue-select', ssr: false } ]
Конечно, не загружайте как файл поставщика:
// nuxt.config.js build: { vendor: ['vue-select'] }
Не стесняйтесь сообщить мне, если вы застряли с интеграцией другого плагина, и я могу попытаться помочь.
Ваше здоровье!