Написание универсального кода

Прежде чем идти дальше, давайте немного обсудим ограничения при написании «универсального» кода — кода, который выполняется как на сервере, так и на клиенте. Из-за различий в API платформы, поведение нашего кода будет отличаться при работе в разных средах выполнения. Здесь мы рассмотрим ключевые моменты, которые нужно вам нужно знать.

Реактивность данных на сервере

В приложении, которое работает только на клиенте, каждый пользователь использует свежий экземпляр приложения в своём браузере. Для рендеринга на стороне сервера мы хотим того же: каждый запрос должен иметь свежий, изолированный экземпляр приложения, чтобы не возникало загрязнения состояния при перекрёстных запросах.

Поскольку фактический процесс рендеринга должен быть детерминированным, мы также будем «предзагружать» данные на сервере — это означает, что состояние приложения будет разрешённым, на момент начала рендеринга. А это означает, что на сервере реактивность данных не нужна, поэтому по умолчанию она отключена. Отключение реактивности данных также позволяет избежать уменьшения производительности из-за отсутствия необходимости преобразования данных в реактивные объекты.

Хуки жизненного цикла компонента

Так как динамических обновлений нет, из всех хуков жизненного цикла будут вызваны только beforeCreate и created во время серверного рендеринга (SSR). Это означает, что код внутри любых других хуков жизненного цикла, таких как beforeMount или mounted, будет выполняться только на клиенте.

Доступ к специализированному API платформы

Универсальный код не может использовать API специализированное для какой-то конкретной платформы (platform-specific APIs), потому что если ваш код будет использовать глобальные переменные браузеров window или document, то возникнут ошибки при выполнении в Node.js, и наоборот.

Для задач, разделяемых между сервером и клиентом, но использующих разные API платформы, рекомендуется создавать обёртки платформо-специфичных реализаций в универсальное API, или использовать библиотеки, которые делают это за вас. Например, axios — это HTTP-клиент предоставляющий одинаковое API как для сервера так и для клиента.

Для API только для браузеров общий подход — ленивый (lazy) доступ к ним, внутри хуков жизненного цикла только для клиентской стороны.

Обратите внимание, что если сторонняя библиотека не была написана с расчётом на универсальное использование, её может быть сложно интегрировать в приложение с серверным рендерингом. Вы могли бы заставить её работать, например создавая моки некоторых глобальных переменных, но это будет грязным хаком и может помешать коду обнаружения окружения в других библиотеках.

Пользовательские директивы

Большинство пользовательских директив непосредственно манипулируют DOM, поэтому будут вызывать ошибки во время SSR. Существует два способа обойти это:

  1. Предпочитайте использовать компоненты в качестве механизма абстракции и работайте на уровне виртуального DOM (например, используя render-функции).

  2. Если у вас есть пользовательская директива, которую нельзя легко заменить компонентами, вы можете предоставить её «серверный вариант» с помощью опции directives при создании серверного рендерера.

results matching ""

    No results matching ""