From bfd61909b0b1d46c359a6b35799d78919f069109 Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Mon, 22 May 2017 09:04:57 +0300 Subject: [PATCH 01/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B1=D1=8D=D0=BA=D1=82=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/data.md | 6 +++--- ru/structure.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ru/data.md b/ru/data.md index 809b78d6..b49f1524 100644 --- a/ru/data.md +++ b/ru/data.md @@ -28,7 +28,7 @@ export function createStore () { }, actions: { fetchItem ({ commit }, id) { - // возвращаем Promise через store.dispatch() + // возвращаем Promise через `store.dispatch()` // чтобы мы могли понять когда данные будут загружены return fetchItem(id).then(item => { commit('setItem', { id, item }) @@ -125,7 +125,7 @@ export default context => { reject({ code: 404 }) } - // вызов asyncData() на всех соответствующих компонентах + // вызов `asyncData()` на всех соответствующих компонентах Promise.all(matchedComponents.map(Component => { if (Component.asyncData) { return Component.asyncData({ @@ -179,7 +179,7 @@ if (window.__INITIAL_STATE__) { // Добавляем хук маршрута для обработки asyncData. // Выполняем его после разрешения первоначального маршрута, // чтобы дважды не загружать данные, которые у нас уже есть. - // Используем router.beforeResolve(), чтобы все асинхронные компоненты были разрешены. + // Используем `router.beforeResolve()`, чтобы все асинхронные компоненты были разрешены. router.beforeResolve((to, from, next) => { const matched = router.getMatchedComponents(to) const prevMatched = router.getMatchedComponents(from) diff --git a/ru/structure.md b/ru/structure.md index 20f78fd6..93438fe2 100644 --- a/ru/structure.md +++ b/ru/structure.md @@ -105,7 +105,7 @@ import { createApp } from './app' const { app } = createApp() -// предполагается, что у корневого элемента в шаблоне App.vue есть элемент с id="app" +// предполагается, что у корневого элемента в шаблоне App.vue есть элемент с `id="app"` app.$mount('#app') ``` From 63a36737684be1d8189987dda763e00ca48b27cf Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Mon, 22 May 2017 14:44:08 +0300 Subject: [PATCH 02/21] =?UTF-8?q?routing.md=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5?= =?UTF-8?q?=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/routing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/routing.md b/ru/routing.md index f0d4f980..a229384b 100644 --- a/ru/routing.md +++ b/ru/routing.md @@ -67,7 +67,7 @@ export default context => { const matchedComponents = router.getMatchedComponents() // нет подходящих маршрутов, отклоняем с 404 if (!matchedComponents.length) { - reject({ code: 404 }) + return reject({ code: 404 }) } // Promise должен разрешиться экземпляром приложения, который будет отрендерен From 5b07856b1deaf3f8e7a3e05430495ae15976d534 Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Mon, 22 May 2017 15:09:28 +0300 Subject: [PATCH 03/21] =?UTF-8?q?data.md=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/data.md b/ru/data.md index b49f1524..06ab5366 100644 --- a/ru/data.md +++ b/ru/data.md @@ -122,7 +122,7 @@ export default context => { router.onReady(() => { const matchedComponents = router.getMatchedComponents() if (!matchedComponents.length) { - reject({ code: 404 }) + return reject({ code: 404 }) } // вызов `asyncData()` на всех соответствующих компонентах From dfba0d6f58d7c64c26a014c5f540a535b473a29a Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Sat, 27 May 2017 14:27:47 +0300 Subject: [PATCH 04/21] =?UTF-8?q?data.md=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=B1=D1=8D=D0=BA=D1=82=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/data.md b/ru/data.md index 06ab5366..f2491663 100644 --- a/ru/data.md +++ b/ru/data.md @@ -138,7 +138,7 @@ export default context => { // заполнено состоянием, необходимым для рендеринга приложения. // Когда мы присоединяем состояние к контексту, и есть опция `template` // используемая для рендерера, состояние будет автоматически - // сериализовано и внедрено в HTML как window.__INITIAL_STATE__. + // сериализовано и внедрено в HTML как `window.__INITIAL_STATE__`. context.state = store.state resolve(app) From d9df311e02c90e9635787cc89021b1eaed6363b4 Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Tue, 27 Jun 2017 14:59:48 +0300 Subject: [PATCH 05/21] =?UTF-8?q?data.md=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/data.md b/ru/data.md index f2491663..72971abf 100644 --- a/ru/data.md +++ b/ru/data.md @@ -215,7 +215,7 @@ if (window.__INITIAL_STATE__) { 2. **Загружать данные после отображения нового представления:** - Эта стратегия располагает логику загрузки данных на стороне клиента в функции компонента `beforeMount`. Это позволяет переключаться мгновенно при срабатывании навигации по маршруту, поэтому приложение ощущается более отзывчивым. Однако на момент отображения нового представления у него не будет полных данных. Поэтому необходимо иметь добавлять условие проверки загруженности состояния для каждого компонента, использующего эту стратегию. + Эта стратегия располагает логику загрузки данных на стороне клиента в функции компонента `beforeMount`. Это позволяет переключаться мгновенно при срабатывании навигации по маршруту, поэтому приложение ощущается более отзывчивым. Однако на момент отображения нового представления у него не будет полных данных. Поэтому необходимо добавлять условие проверки загруженности состояния для каждого компонента, использующего эту стратегию. Этого можно достичь с помощью глобальной примеси на клиенте: From ec41ef31756f6ef48839de3d196e73fd6d865a69 Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Fri, 30 Jun 2017 08:56:32 +0300 Subject: [PATCH 06/21] =?UTF-8?q?universal.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/universal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/universal.md b/ru/universal.md index 60179795..45436633 100644 --- a/ru/universal.md +++ b/ru/universal.md @@ -1,6 +1,6 @@ # Написание универсального кода -Прежде чем идти дальше, давайте немного обсудим ограничения при написании «универсального» кода — кода, который выполняется как на сервере, так и на клиенте. Из-за различий в API платформы, поведение нашего кода будет отличаться при работе в разных средах выполнения. Здесь мы рассмотрим ключевые моменты, которые нужно вам нужно знать. +Прежде чем идти дальше, давайте немного обсудим ограничения при написании «универсального» кода — кода, который выполняется как на сервере, так и на клиенте. Из-за различий в API платформы, поведение нашего кода будет отличаться при работе в разных средах выполнения. Здесь мы рассмотрим ключевые моменты, которые вам нужно знать. ## Реактивность данных на сервере From fa8c52a4f1664c5314facb081bde58ae02317e5f Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Fri, 30 Jun 2017 09:08:16 +0300 Subject: [PATCH 07/21] =?UTF-8?q?universal.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/universal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/universal.md b/ru/universal.md index 45436633..0bf7151c 100644 --- a/ru/universal.md +++ b/ru/universal.md @@ -22,7 +22,7 @@ Для API только для браузеров общий подход — ленивый (lazy) доступ к ним, внутри хуков жизненного цикла только для клиентской стороны. -Обратите внимание, что если сторонняя библиотека не была написана с расчётом на универсальное использование, её может быть сложно интегрировать в приложение с серверным рендерингом. Вы *могли бы* заставить её работать, например создавая моки некоторых глобальных переменных, но это будет грязным хаком и может помешать коду обнаружения окружения в других библиотеках. +Обратите внимание, если сторонняя библиотека не была написана с расчётом на универсальное использование, её может быть сложно интегрировать в приложение с серверным рендерингом. Вы *могли бы* заставить её работать, например создавая моки некоторых глобальных переменных, но это будет грязным хаком и может помешать коду обнаружения окружения в других библиотеках. ## Пользовательские директивы From 568204173242605afa2fa6b149272d86e386e5d3 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Jul 2017 22:18:31 +0300 Subject: [PATCH 08/21] =?UTF-8?q?api.md=20=D0=BE=D0=BF=D0=B5=D1=87=D0=B0?= =?UTF-8?q?=D1=82=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/api.md b/ru/api.md index 43e6c079..05de5a5c 100644 --- a/ru/api.md +++ b/ru/api.md @@ -131,7 +131,7 @@ const renderer = createBundleRenderer(serverBundle, { ... }) - используется только в `createBundleRenderer` - Ожидается: `boolean | 'once'` (`'once'` поддерживается только с версии 2.3.1+) - По умолчанию, рендерер сборки будет создавать новый контекст V8 для каждого рендеринга и повторно исполнять всю сборку. Это имеет некоторые преимущества — например, код приложения изолирован от процесса сервера и не нужно беспокоиться [о проблеме «синглетона с состоянием»](./structure.md#avoid-stateful-singletons), которая упоминалась ранее в руководстве. Однако этот режим требует значительных затрат производительности, поскольку повторное выполнение сборки обходится дорого, особенно когда приложение становится большим. + По умолчанию, рендерер сборки будет создавать новый контекст V8 для каждого рендеринга и повторно исполнять всю сборку. Это имеет некоторые преимущества — например, код приложения изолирован от процесса сервера и не нужно беспокоиться [о проблеме «синглтона с состоянием»](./structure.md#avoid-stateful-singletons), которая упоминалась ранее в руководстве. Однако этот режим требует значительных затрат производительности, поскольку повторное выполнение сборки обходится дорого, особенно когда приложение становится большим. По умолчанию эта опция имеет значение `true` для обеспечения обратной совместимости, но рекомендуется использовать `runInNewContext: false` или `runInNewContext: 'once'` всегда, когда это возможно. From 3d7ef5cae3cbcfeefc3167d997b763d5010e3f33 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Thu, 20 Jul 2017 22:18:39 +0300 Subject: [PATCH 09/21] =?UTF-8?q?structure.md=20=D0=BE=D0=BF=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D1=82=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/structure.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ru/structure.md b/ru/structure.md index 93438fe2..e7be6e22 100644 --- a/ru/structure.md +++ b/ru/structure.md @@ -1,8 +1,8 @@ # Структура исходного кода -## Избегайте синглетонов с состоянием +## Избегайте синглтонов с состоянием -При написании кода для клиентской стороны мы привыкли к тому, что наш код каждый раз будет выполняться в новом контексте. Однако сервер Node.js является длительным процессом (long-running process). Поэтому когда наш код потребуется, он будет выполнен один раз и останется в памяти. Это означает, что если вы создаёте объект синглетон, он будет использоваться для всех входящих запросов. +При написании кода для клиентской стороны мы привыкли к тому, что наш код каждый раз будет выполняться в новом контексте. Однако сервер Node.js является длительным процессом (long-running process). Поэтому когда наш код потребуется, он будет выполнен один раз и останется в памяти. Это означает, что если вы создаёте объект синглтон, он будет использоваться для всех входящих запросов. Как видно из простого примера, мы **создаём новый корневой экземпляр Vue для каждого запроса**. Это схоже с тем, когда каждый пользователь будет использовать свежий экземпляр приложения в своём браузере. Если мы будем использовать общий экземпляр для нескольких запросов, то это быстро приведёт к загрязнению состояния. From 95a764d8761d6fb9f52cb0915edc48296fb27816 Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Mon, 11 Sep 2017 10:33:22 +0300 Subject: [PATCH 10/21] =?UTF-8?q?head.md=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/head.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/head.md b/ru/head.md index 4beff90a..51494c4a 100644 --- a/ru/head.md +++ b/ru/head.md @@ -52,7 +52,7 @@ export default { mixins: [titleMixin], title () { return this.item.title - } + }, asyncData ({ store, route }) { return store.dispatch('fetchItem', route.params.id) From a7b83ad9c4488f028c82b6290822dfdaf84d02b0 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Wed, 13 Sep 2017 23:04:41 +0300 Subject: [PATCH 11/21] =?UTF-8?q?README.md=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=81=D1=81=D1=8B=D0=BB?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BD=D0=B0=20HTTPS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/README.md b/ru/README.md index 84d1c08d..9bed53b9 100644 --- a/ru/README.md +++ b/ru/README.md @@ -43,7 +43,7 @@ Vue.js — это фреймворк для создания приложени Это руководство ориентировано на SPA приложения с рендерингом на сервере, используя Node.js в качестве сервера. Использование серверного рендеринга Vue совместно с другими технологиями и настройками бэкэнда являются отдельной темой и не рассматриваются в этом руководстве. -Это руководство будет очень детальным и предполагает, что вы уже знакомы с самим Vue.js, имеете знания и опыт работы с Node.js и Webpack. Если вы предпочитаете более высокоуровневые решения, обеспечивающие работу из коробки — вам следует попробовать [Nuxt.js](http://nuxtjs.org/). Он построен на том же стеке Vue, но позволяет абстрагироваться от написания шаблонного кода, а также предоставляет некоторые дополнительные возможности, такие как генерация статичного сайта. Однако он может не подойти, если вам необходим полный контроль над структурой приложения. В любом случае, вам будет полезно прочитать это руководство, чтобы лучше понимать, как все составляющие работают вместе. +Это руководство будет очень детальным и предполагает, что вы уже знакомы с самим Vue.js, имеете знания и опыт работы с Node.js и Webpack. Если вы предпочитаете более высокоуровневые решения, обеспечивающие работу из коробки — вам следует попробовать [Nuxt.js](https://nuxtjs.org/). Он построен на том же стеке Vue, но позволяет абстрагироваться от написания шаблонного кода, а также предоставляет некоторые дополнительные возможности, такие как генерация статичного сайта. Однако он может не подойти, если вам необходим полный контроль над структурой приложения. В любом случае, вам будет полезно прочитать это руководство, чтобы лучше понимать, как все составляющие работают вместе. По мере прочтения руководства, будет полезным обращаться к официальному [демо HackerNews](https://github.com/vuejs/vue-hackernews-2.0/), в котором используется большинство техник, изложенных в этом руководстве. From 424505298b2de478876baadb12bb6b3c55e023f3 Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Wed, 20 Sep 2017 15:10:32 +0300 Subject: [PATCH 12/21] =?UTF-8?q?caching.md=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/caching.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/caching.md b/ru/caching.md index 6f8314fe..0784a156 100644 --- a/ru/caching.md +++ b/ru/caching.md @@ -69,7 +69,7 @@ export default { Обратите внимание, что подлежащий кэшированию компонент **также должен определять уникальную опцию `name`**. С уникальным именем ключ кэша таким образом является компоненто-зависимым: вам не нужно беспокоиться о двух компонентах, возвращающих одинаковый ключ. -Ключ, возвращаемый из `serverCacheKey` должен содержать достаточную информацию для представления формы результата рендеринга. Указанное выше является хорошей реализацией, если результат рендеринга определяется исключительно с помощью `props.item.id`. Однако, если элемент с таким же идентификатором может со временем меняться или результат рендеринга также зависит от других данных, вам необходимо изменить реализацию `getCacheKey`, чтобы учитывать и другие переменные. +Ключ, возвращаемый из `serverCacheKey` должен содержать достаточную информацию для представления формы результата рендеринга. Указанное выше является хорошей реализацией, если результат рендеринга определяется исключительно с помощью `props.item.id`. Однако, если элемент с таким же идентификатором может со временем меняться или результат рендеринга также зависит от других данных, вам необходимо изменить реализацию `serverCacheKey`, чтобы учитывать и другие переменные. При возвращении константы компонент всегда будет кэшироваться, что отлично подходит для чисто статических компонентов. From 06c34393bc20a6d6e92b47d7d91e4627877653d4 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Sat, 14 Oct 2017 12:49:49 +0300 Subject: [PATCH 13/21] =?UTF-8?q?api.md=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BA=202.5.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/api.md | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/ru/api.md b/ru/api.md index 05de5a5c..0c64fbf3 100644 --- a/ru/api.md +++ b/ru/api.md @@ -30,23 +30,27 @@ const renderer = createBundleRenderer(serverBundle, { ... }) ## `Класс: Renderer` -- #### `renderer.renderToString(vm[, context], callback)` +- #### `renderer.renderToString(vm[, context, callback]): ?Promise` Рендерит экземпляр Vue в строку. Объект контекста опционален. Коллбэк является обычным для Node.js коллбэком, где первый аргумент является ошибкой, а второй аргумент — отрендеренной строкой. -- #### `renderer.renderToStream(vm[, context])` + С версии 2.5.0+ коллбэк является опциональным. Когда коллбэк не указан, метод возвращает Promise, который разрешается отрендеренным HTML. - Рендерит экземпляр Vue в поток (stream) Node.js. Объект контекста опционален. См. также [Стриминг](./streaming.md) для подробностей. +- #### `renderer.renderToStream(vm[, context]): stream.Readable` + + Рендерит экземпляр Vue в [Node.js readable stream](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_readable_streams). Объект контекста опционален. См. также [Стриминг](./streaming.md) для подробностей. ## `Класс: BundleRenderer` -- #### `bundleRenderer.renderToString([context, ]callback)` +- #### `bundleRenderer.renderToString([context, callback]): ?Promise` Рендерит сборку в строку. Объект контекста опционален. Коллбэк является обычным для Node.js коллбэком, где первый аргумент является ошибкой, а второй аргумент — отрендеренной строкой. -- #### `bundleRenderer.renderToStream([context])` + С версии 2.5.0+ коллбэк является опциональным. Когда коллбэк не указан, метод возвращает Promise, который разрешается отрендеренным HTML. + +- #### `bundleRenderer.renderToStream([context]): stream.Readable` - Рендерит сборку в поток (stream) Node.js. Объект контекста опционален. См. также [Стриминг](./streaming.md) для подробностей. + Рендерит сборку в [Node.js readable stream](https://nodejs.org/dist/latest-v8.x/docs/api/stream.html#stream_readable_streams). Объект контекста опционален. См. также [Стриминг](./streaming.md) для подробностей. ## Настройки рендерера @@ -67,6 +71,8 @@ const renderer = createBundleRenderer(serverBundle, { ... }) - `context.state`: (Object) начальное состояние хранилища Vuex, которое должно быть внедрено в страницу как `window.__INITIAL_STATE__`. Внедряемый JSON автоматически обрабатывается с помощью [serialize-javascript](https://github.com/yahoo/serialize-javascript) для предотвращения XSS-уязвимостей. + С версии 2.5.0+, встраиваемый скрипт также автоматически удаляется в режиме production. + Кроме того, когда предоставлен `clientManifest`, шаблон автоматически внедряет следующее: - JavaScript и CSS ресурсы для клиентской части, необходимые для рендеринга (с асинхронными фрагментами добавляемыми автоматически); @@ -81,13 +87,13 @@ const renderer = createBundleRenderer(serverBundle, { ... }) - #### `clientManifest` - - 2.3.0+ + - Добавлено в версии 2.3.0+ Предоставляет объект манифеста клиентской сборки, сгенерированный `vue-server-renderer/client-plugin`. Клиентский манифест предоставляет для рендерера сборки необходимую информацию для автоматического внедрения ресурсов в шаблон HTML. Подробнее в разделе [Генерация `clientManifest`](./build-config.md#generating-clientmanifest). - #### `inject` - - 2.3.0+ + - Добавлено в версии 2.3.0+ Контролирует, выполнять ли автоматические внедрения при использовании `template`. По умолчанию `true`. @@ -95,7 +101,7 @@ const renderer = createBundleRenderer(serverBundle, { ... }) - #### `shouldPreload` - - 2.3.0+ + - Добавлено в версии 2.3.0+ Функция, определяющая какие файлы должны иметь `` в генерируемых ресурсах. @@ -125,10 +131,18 @@ const renderer = createBundleRenderer(serverBundle, { ... }) }) ``` +- #### `shouldPrefetch` + + - Добавлено в версии 2.5.0+ + + Функция для управления файлами, которые должны содержаться в генерируемых ``. + + По умолчанию все ресурсы в асинхронных частях будут предварительно загружены, так как это директива с низким приоритетом; однако вы можете настроить что требуется предзагружать для лучшего контроля над использованием канала загрузки. Этот параметр ожидает такую же сигнатуру функции, как `shouldPreload`. + - #### `runInNewContext` - - 2.3.0+ - - используется только в `createBundleRenderer` + - Добавлено в версии 2.3.0+ + - Используется только в `createBundleRenderer` - Ожидается: `boolean | 'once'` (`'once'` поддерживается только с версии 2.3.1+) По умолчанию, рендерер сборки будет создавать новый контекст V8 для каждого рендеринга и повторно исполнять всю сборку. Это имеет некоторые преимущества — например, код приложения изолирован от процесса сервера и не нужно беспокоиться [о проблеме «синглтона с состоянием»](./structure.md#avoid-stateful-singletons), которая упоминалась ранее в руководстве. Однако этот режим требует значительных затрат производительности, поскольку повторное выполнение сборки обходится дорого, особенно когда приложение становится большим. @@ -148,8 +162,8 @@ const renderer = createBundleRenderer(serverBundle, { ... }) - #### `basedir` - - 2.2.0+ - - используется только в `createBundleRenderer` + - Добавлено в версии 2.2.0+ + - Используется только в `createBundleRenderer` Указание пути базового каталога для серверной сборки для разрешения зависимостей из `node_modules` в нём. Это необходимо только в том случае, если сгенерированный файл сборки располагается в другом месте, в отличии от используемых NPM-зависимостей, или когда ваш `vue-server-renderer` подключен NPM-ссылкой в вашем текущем проекте. From 1fbb67fda9a2e8a8a1e67affcb654aa247205deb Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Sat, 14 Oct 2017 12:50:02 +0300 Subject: [PATCH 14/21] =?UTF-8?q?basic.md=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20=D0=B4=D0=BB=D1=8F=202.5.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/basic.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ru/basic.md b/ru/basic.md index 5a8ef8d9..36b27d82 100644 --- a/ru/basic.md +++ b/ru/basic.md @@ -32,6 +32,13 @@ renderer.renderToString(app, (err, html) => { console.log(html) // =>
hello world
}) + +// с версии 2.5.0+, возвращает Promise если коллбэк не указан: +renderer.renderToString.then(html => { + console.log(html) +}).catch(err => { + console.error(err) +}) ``` ## Интеграция с сервером @@ -112,7 +119,7 @@ renderer.renderToString(app, (err, html) => { {{ title }} - + {{{ meta }}} From dece39594588df29ba67d1e54589991228e4538d Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Sat, 14 Oct 2017 12:50:19 +0300 Subject: [PATCH 15/21] =?UTF-8?q?non-node.md=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/non-node.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 ru/non-node.md diff --git a/ru/non-node.md b/ru/non-node.md new file mode 100644 index 00000000..22c8a19f --- /dev/null +++ b/ru/non-node.md @@ -0,0 +1,41 @@ +# Использование в не-Node.js окружениях + +По умолчанию сборка `vue-server-renderer` предполагает использование Node.js окружения, что делает её непригодной для использования в альтернативных JavaScript окружениях, таких как [php-v8js](https://github.com/phpv8/v8js) или [Nashorn](https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/). С версии 2.5 мы предоставляем сборку в `vue-server-renderer/basic.js`, которая в значительной степени менее зависима от окружения, что делает её пригодной для использования в окружениях, упомянутых выше. + +Для обоих вариантов необходимо сначала подготовить окружение создав моки для объектов `global` и `process`, с переменной `process.env.VUE_ENV` установленной в значение `"server"`, и переменной `process.env.NODE_ENV` установленной в значение `"development"` или `"production"`. + +При использовании Nashorn также может потребоваться предоставить полифилл для `Promise` или `setTimeout` с использованием нативных таймеров Java. + +Пример использования в php-v8js: + +``` php +executeString('var process = { env: { VUE_ENV: "server", NODE_ENV: "production" }}; this.global = { process: process };'); +$v8->executeString($vue_source); +$v8->executeString($renderer_source); +$v8->executeString($app_source); +?> +``` + +--- + +``` js +// app.js +var vm = new Vue({ + template: `
{{ msg }}
`, + data: { + msg: 'hello' + } +}) + +// exposed by vue-server-renderer/basic.js +renderVueComponentToString(vm, (err, res) => { + print(res) +}) +``` From 0c2bfe46472c6516ad4023f7d91ab9f1852bc068 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Sat, 14 Oct 2017 12:50:30 +0300 Subject: [PATCH 16/21] =?UTF-8?q?README.md=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/README.md b/ru/README.md index 6180524e..e2c78de4 100644 --- a/ru/README.md +++ b/ru/README.md @@ -41,7 +41,7 @@ Vue.js — это фреймворк для создания приложени ## Об этом руководстве -Это руководство ориентировано на SPA приложения с рендерингом на сервере, используя Node.js в качестве сервера. Использование серверного рендеринга Vue совместно с другими технологиями и настройками бэкэнда являются отдельной темой и не рассматриваются в этом руководстве. +Это руководство ориентировано на SPA приложения с рендерингом на сервере, используя Node.js в качестве сервера. Использование серверного рендеринга Vue совместно с другими технологиями и настройками бэкэнда являются отдельной темой и кратко обсуждается в [отдельном разделе](./non-node.md). Это руководство будет очень детальным и предполагает, что вы уже знакомы с самим Vue.js, имеете знания и опыт работы с Node.js и Webpack. Если вы предпочитаете более высокоуровневые решения, обеспечивающие работу из коробки — вам следует попробовать [Nuxt.js](https://nuxtjs.org/). Он построен на том же стеке Vue, но позволяет абстрагироваться от написания шаблонного кода, а также предоставляет некоторые дополнительные возможности, такие как генерация статичного сайта. Однако он может не подойти, если вам необходим полный контроль над структурой приложения. В любом случае, вам будет полезно прочитать это руководство, чтобы лучше понимать, как все составляющие работают вместе. From 411015b687268d9797b0fd48665d5144fc30e77c Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Sat, 14 Oct 2017 12:50:41 +0300 Subject: [PATCH 17/21] =?UTF-8?q?SUMMARY.md=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=81=D1=81=D1=8B=D0=BB=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=20=D0=B2=20=D0=BE=D0=B3=D0=BB?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/SUMMARY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ru/SUMMARY.md b/ru/SUMMARY.md index 5fb37d1c..8d0f9834 100644 --- a/ru/SUMMARY.md +++ b/ru/SUMMARY.md @@ -10,6 +10,7 @@ - [Управление заголовочными тегами (head)](head.md) - [Кэширование](caching.md) - [Стриминг](streaming.md) +- [Использование в не-Node.js окружениях](non-node.md) - [Справочник API](api.md) - [createRenderer](api.md#createrendereroptions) - [createBundleRenderer](api.md#createbundlerendererbundle-options) From babdc95054574ad669d7379eaf66fc5d87e66f25 Mon Sep 17 00:00:00 2001 From: Alex-Sokolov Date: Sat, 14 Oct 2017 12:53:00 +0300 Subject: [PATCH 18/21] =?UTF-8?q?non-node.md=20=D0=B4=D0=BE=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/non-node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/non-node.md b/ru/non-node.md index 22c8a19f..e16308b0 100644 --- a/ru/non-node.md +++ b/ru/non-node.md @@ -34,7 +34,7 @@ var vm = new Vue({ } }) -// exposed by vue-server-renderer/basic.js +// предоставляется vue-server-renderer/basic.js renderVueComponentToString(vm, (err, res) => { print(res) }) From b2e0e5dcbbc64bdf592acb7273c8f11c27c0e6ab Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Wed, 18 Oct 2017 09:16:05 +0300 Subject: [PATCH 19/21] =?UTF-8?q?hydration.md=20=D0=BD=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/hydration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ru/hydration.md b/ru/hydration.md index 1ea85d7a..adac2d35 100644 --- a/ru/hydration.md +++ b/ru/hydration.md @@ -9,13 +9,13 @@ app.$mount('#app') Поскольку сервер уже отобразил разметку, мы, очевидно, не хотели бы её выбрасывать и заново создавать все элементы DOM. Вместо этого мы хотим «гидрировать» статическую разметку и сделать её интерактивной. -Если вы исследовали вывод после серверного рендеринга, вы могли заметить, что у корневого элемента приложения есть специальный атрибут: +Если вы исследовали вывод после серверного рендеринга, вы могли заметить, что у корневого элемента приложения должен быть добавлен специальный атрибут: ``` js
``` -Специальный атрибут `data-server-rendered` позволяет клиентской части Vue знать, что разметка отображается сервером, и он должен монтироваться в режиме гидратации. +Специальный атрибут `data-server-rendered` позволяет клиентской части Vue знать, что разметка отображается сервером, и он должен монтироваться в режиме гидратации. Обратите внимание, что он не добавляет `id="app"`, а только атрибут `data-server-rendered`: вам необходимо добавить ID или какой-либо другой селектор в корневой элемент самостоятельно или приложение не будет гидратироваться правильно. В режиме разработки Vue будет проверять, что виртуальное дерево DOM, сгенерированное на стороне клиента, совпадает с структурой DOM созданной на сервере. При нахождении несоответствия, он будет считать гидратацию неудачной, отказываться от существующего DOM и рендерить всё с нуля. **В режиме production, эта проверка отключена для достижения максимальной производительности.** From fa181fda6ba67902a95ab6b06e3255005f8c197e Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Wed, 18 Oct 2017 09:16:59 +0300 Subject: [PATCH 20/21] =?UTF-8?q?non-node.md=20=D0=BC=D0=B5=D0=BB=D0=BA?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/non-node.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ru/non-node.md b/ru/non-node.md index e16308b0..c7458bfe 100644 --- a/ru/non-node.md +++ b/ru/non-node.md @@ -1,6 +1,6 @@ # Использование в не-Node.js окружениях -По умолчанию сборка `vue-server-renderer` предполагает использование Node.js окружения, что делает её непригодной для использования в альтернативных JavaScript окружениях, таких как [php-v8js](https://github.com/phpv8/v8js) или [Nashorn](https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/). С версии 2.5 мы предоставляем сборку в `vue-server-renderer/basic.js`, которая в значительной степени менее зависима от окружения, что делает её пригодной для использования в окружениях, упомянутых выше. +По умолчанию сборка `vue-server-renderer` предполагает использование Node.js окружения, что делает её непригодной для использования в альтернативных JavaScript окружениях, таких как [PHP V8Js](https://github.com/phpv8/v8js) или [Oracle Nashorn](https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/). С версии 2.5+ мы предоставляем сборку в `vue-server-renderer/basic.js`, которая в значительной степени менее зависима от окружения, что делает её пригодной для использования в окружениях, упомянутых выше. Для обоих вариантов необходимо сначала подготовить окружение создав моки для объектов `global` и `process`, с переменной `process.env.VUE_ENV` установленной в значение `"server"`, и переменной `process.env.NODE_ENV` установленной в значение `"development"` или `"production"`. @@ -34,7 +34,7 @@ var vm = new Vue({ } }) -// предоставляется vue-server-renderer/basic.js +// предоставляется `vue-server-renderer/basic.js` renderVueComponentToString(vm, (err, res) => { print(res) }) From 2e448d0dc5fe071e5831f8e4208664601326e1e5 Mon Sep 17 00:00:00 2001 From: Alex Sokolov Date: Thu, 19 Oct 2017 17:09:19 +0300 Subject: [PATCH 21/21] =?UTF-8?q?basic.md=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/basic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/basic.md b/ru/basic.md index 36b27d82..498c4613 100644 --- a/ru/basic.md +++ b/ru/basic.md @@ -34,7 +34,7 @@ renderer.renderToString(app, (err, html) => { }) // с версии 2.5.0+, возвращает Promise если коллбэк не указан: -renderer.renderToString.then(html => { +renderer.renderToString(app).then(html => { console.log(html) }).catch(err => { console.error(err)