Угловой универсальный и серверный рендеринг (шаг за шагом)

  1. Что такое Angular Universal?
  2. Рендеринг угловой на сервере
  3. Классический подход:
  4. Предоставленная сторона сервера:
  5. Статический против Динамического
  6. статический
  7. динамический
  8. Рендеринг во время сборки
  9. Почему вы должны рендерить на сервере?
  10. SEO
  11. Пользовательский опыт
  12. Угловая универсальная: серебряная пуля?
  13. Требуется сервер
  14. Не легко настроить
  15. Угловой универсальный пример [шаг за шагом]
  16. Создание дополнительных модулей
  17. Модуль браузера
  18. Серверный модуль
  19. Создание второго приложения для CLI
  20. Рендеринг на стороне сервера
  21. Настройка сервера динамического рендеринга
  22. Создание сервера Node.js
  23. Настройка статического рендерера
  24. Настроить
  25. Настройка сервера для поддержки отложенной загрузки
  26. API Angular Transfer State (только Angular 5)
  27. Но как мы можем улучшить это?
  28. Реализация API состояния передачи
  29. Использование API Transfer State
  30. Заключение

Вы, вероятно, согласны со мной, когда я говорю:

С Angular Universal нелегко разобраться с первого раза.

Что ж, оказывается, это совсем не сложно!

Как только вы поймете, как это работает на самом деле, вам будет легко настроить работающее приложение. На самом деле, создание полнофункционального углового универсального приложения не займет у вас больше 1 часа!

В этом уроке я покажу вам, что такое угловая универсальность и как она работает. Как только мы получим основы, мы погрузимся прямо в код! Превратив базовый проект angular-cli в функциональное универсальное приложение, вы не только увидите, как это делается шаг за шагом. Вы также получите рабочий шаблон для рендеринга на стороне сервера, который вы можете использовать для будущих угловых приключений. Все, что вам нужно, чтобы начать это универсальное угловое руководство.

Итак, давайте погрузимся прямо в! Итак, давайте погрузимся прямо в

Что такое Angular Universal?

Угловой универсальный Когда-то это был отдельный проект. Его главная цель состояла в том, чтобы дать возможность угловым работать полностью независимо от платформы.

"Подождите? Почему ты говоришь в прошедшем времени?

Потому что с версии 4.0 angular, angular universal слился в основной каркас. Теперь он поставляется вместе с основными угловыми пакетами. Имена пакетов: платформа-сервер и платформа-браузер.

Angular теперь может работать одинаково на большинстве платформ. Самое главное, он может быть запущен на сервере сейчас. Это обеспечивает целый набор новых возможностей, таких как рендеринг под углом в html на сервере. Но как это вообще работает?

Рендеринг угловой на сервере

По своей сути angular - это просто html-парсер. Когда вы создаете свое угловое приложение, ваши шаблоны анализируются из разметки HTML в код JavaScript. Этот код JavaScript создаст проанализированные HTML-элементы во время выполнения в браузере. Но рендеринг этого HTML теперь требует загрузки полной угловой (основной) инфраструктуры.

Как мы узнали ранее, angular также может работать на серверах node.js. Из-за этого также возможно генерировать этот проанализированный HTML на сервере. В результате получается просто HTML, который сервер затем может отправить клиенту.

Классический подход:

Вот как обычно загружается угловой. Угловой каркас должен быть загружен. Пользователь ничего не видит в своем окне браузера, пока полный угловой код не будет загружен и загружен. Вот как обычно загружается угловой

Предоставленная сторона сервера:

Когда мы выполняем рендеринг на сервере под углом, все, что нужно для перемещения по проводам, - это сам html. Чтобы дать вам некоторые цифры здесь. HTML-документ для статьи в блоге может быть скачан около 50 КБ. Конечно, не считая изображений. С другой стороны, вам будет нелегко довести угол до 150кб в сжатом виде. И этот номер не содержит содержания самой страницы. Это просто размер угловых файлов JavaScript. Это более чем в три раза больше! Теперь представьте своих мобильных пользователей. Это в три раза больше времени, которое загружает ваше приложение (приблизительно).

Статический против Динамического

Теперь мы знаем разницу между обоими методами, оказывается, что существует несколько вариантов рендеринга на стороне сервера.

статический

Первый - тот, который вы видите на картинке выше. Мы отображаем HTML-код нашей страницы / приложения. Этот HTML-код содержит только сам HTML-код и необходимый CSS-код для отображения страницы. В этих данных нет JavaScript. Это может быть хорошо или плохо. Это хорошо, если мы не полагаемся на JavaScript для нашего приложения. Это может иметь место при отображении поста в блоге. Поскольку нам не нужен JavaScript, размер загружаемых данных относительно невелик. Если вы полагаетесь на JavaScript, например, чтобы показать всплывающее окно, которое не может работать, если оно не включено в загруженный файл. Конечно, есть способы обойти это, но это довольно быстро. Узнайте больше об этом в этом статья о типичных ошибках при рендеринге на стороне сервера ,

динамический

Другой возможный метод можно назвать динамическим. Используя этот метод, мы все равно визуализируем наш HTML на сервере. Но на этот раз мы также включаем теги сценариев, которые инструктируют браузер загружать угловой код после полной загрузки страницы. Таким образом, страница может быть доставлена ​​гораздо быстрее, чем обслуживая фреймворк с самого начала. В то же время мы все еще можем использовать все функции JavaScript, на которые мы могли бы положиться.

Примечание. Поскольку первоначальная версия нашего приложения по-прежнему не содержит JavaScript, мы все равно должны быть осторожны, где его использовать.

Поскольку первоначальная версия нашего приложения по-прежнему не содержит JavaScript, мы все равно должны быть осторожны, где его использовать

После полной загрузки JavaScript приложение загружается и заменяет статическую версию HTML. Начиная с этого момента, мы можем рассчитывать на выполнение кода JavaScript, например, показать наше всплывающее окно.

Рендеринг во время сборки

Другим возможным решением может быть рендеринг статического HTML во время сборки. При этом, однако, вам придется пересобирать каждый раз, когда меняется ваш динамический контент. Этот метод избавляет вас от настройки производственного сервера. С другой стороны. этот метод может очень быстро запутаться. Я бы порекомендовал его, только если у вас нет динамического контента, или он почти никогда не меняется. Другим возможным решением может быть рендеринг статического HTML во время сборки

Почему вы должны рендерить на сервере?

На данный момент, вы можете подумать:

«Почему мы вообще думаем обо всем этом?»

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

SEO

«Поисковая оптимизация» , Поскольку угловые приложения в большой степени зависят от JavaScript, большинство поисковых систем испытывают проблемы с очисткой содержимого приложения. На самом деле, большинство поисковых систем даже не выполняют JavaScript. В этом случае мы представили бы им пустую страницу. Ой! Чтобы предотвратить это, мы можем визуализировать наше приложение на сервере и отправить обратно обработанный HTML. В результате получается простой HTML, теперь сканер может правильно проиндексировать нашу страницу.

Поисковые системы - не единственные, которые бунтуют, когда видят JavaScript. Большинство скребков контента сайтов социальных сетей также игнорируют JavaScript. Поэтому, когда мы публикуем ссылку на нашу страницу, мы не получим милую маленькую карточку с нашей страницей. Опять же, у них нет проблем с обработкой HTML. Примерами сайтов социальных сетей, которые используют скребки контента, являются Facebook, Twitter, Reddit и многие другие.

Пользовательский опыт

Как упоминалось выше, приложение / страница могут быть показаны пользователю намного быстрее, если используется рендеринг на стороне сервера. Это имеет к причинам. Во-первых, общий размер файла намного меньше, потому что он содержит только HTML. Кроме того, браузер может немедленно начать рендеринг страницы. В обычных угловых приложениях приложение должно быть загружено, прежде чем что-либо может быть показано пользователю, что занимает дополнительное время. Как упоминалось выше, приложение / страница могут быть показаны пользователю намного быстрее, если используется рендеринг на стороне сервера

Угловая универсальная: серебряная пуля?

Хотя рендеринг на стороне сервера (angular 4 universal) имеет много преимуществ, он также имеет свои недостатки. Вот некоторые из них:

Требуется сервер

Как уже предполагает рендеринг на стороне сервера имен, веб-сервер необходим для предварительного рендеринга страниц. В то время как обычные угловые приложения содержат только статические файлы, при рендеринге на стороне сервера нам нужно вычислять HTML во время выполнения. Так почему же это недостаток? Ну, хотя хостинг не стоит миру, он обычно не бесплатный / дешевый. Не упоминать административные усилия для поддержки сервера. С другой стороны, со статическими файлами вы можете получить статический хостинг файлов бесплатно или очень дешево. Кроме того, эти услуги обычно очень хорошо масштабируются, без каких-либо усилий на вашей стороне.

Не легко настроить

Команда Angular планирует сделать рендеринг на стороне сервера очень простым, интегрировав его в клиентскую среду. На данный момент, однако, это не слишком легко настроить. Это требует, чтобы вы знали все вещи, которые в настоящее время не работают на стороне сервера, и полностью их избегаете. Кроме того, вам, вероятно, нужно разобраться с основами работы рендеринга на стороне сервера с угловым режимом, что потребует от вас заглянуть под капот. В универсальном проекте есть модули, которые пытаются отобрать это у вас, но они все еще находятся в бета-версии. Команда Angular планирует сделать рендеринг на стороне сервера очень простым, интегрировав его в клиентскую среду

Угловой универсальный пример [шаг за шагом]

В следующих главах мы создадим базовое угловое приложение, используя angular-cli.

После этого мы собираемся подготовить его для рендеринга на стороне сервера. Мы также собираемся внедрить необходимый сервер в node.js.

Итак, давайте создадим новое приложение, используя angular-cli:

нг новый рендеринг на стороне сервера

Сгенерированное приложение будет основой для наших следующих шагов.

Чтобы подготовить наше приложение для рендеринга на стороне сервера, нам нужно будет внести некоторые коррективы. Поскольку код, выполняемый на сервере, немного отличается от кода в браузере, наше приложение должно иметь две точки входа. Также у нас будет два отдельных корневых модуля, что позволит нам импортировать разные модули на сервер. Нам нужна эта функциональность, потому что не все модули совместимы с рендерингом на стороне сервера. Особенно сторонние.

Кроме того, некоторые функции просто не нужно отображать на сервере. Какой смысл иметь, например, Google Analytics на сервере?

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

Итак, начнем!

Создание дополнительных модулей

Для начала нам нужно создать два дополнительных модуля в каталоге приложений. Рядом с app.module.ts создайте файл с именем browser.app.module.ts и файл с именем server.app.module.ts. Если вы хотите узнать больше о модулях, проверьте это статья об угловых модулях !

Модуль браузера

Модуль приложения для браузера очень прост. Все, что нам нужно сделать, это вызвать BrowserModule.withServerTransition. Этот метод сообщает angular, что мы используем рендеринг на стороне сервера и что представление необходимо поменять местами после загрузки полной структуры. Этот метод ожидает объект с ключом с именем appId. Вы можете ввести любую строку здесь. Просто убедитесь, что строка в нашем модуле приложения браузера совпадает со строкой в ​​модуле приложения сервера.

src / app / browser.app.module.ts import {AppModule} из './app.module' import {BrowserModule} из '@ angular / platform-browser' import {NgModule} из '@ angular / core' import {AppComponent } из './app.component' @ NgModule ({объявлений: [], импорт: [BrowserModule. withServerTransition ({appId: 'my-app-id',}), AppModule,], поставщики: [], начальная загрузка: [AppComponent],}) класс BrowserAppModule {}

Возможно, вы заметили, что мы все еще используем AppModule по умолчанию, импортировав его в наш модуль браузера. Мы также будем использовать AppModule в нашем модуле сервера позже. Думайте об этом как об общем модуле между сервером и браузером.

Серверный модуль

На данный момент наш серверный модуль выглядит в основном так же, как модуль браузера. Разница лишь в том, что нам нужно импортировать угловой модуль с именем ServerModule. Этот модуль не установлен angular-cli. Чтобы установить его, используйте одну из следующих команд:

yarn add @ angular / platform-server npm install @ angular / platform-server - сохранить импорт {AppModule} из './app.module'; импортировать {BrowserModule} из '@ angular / platform-browser'; импортировать {NgModule} из '@ angular / core'; // Установлен отдельный импорт {ServerModule} из '@ angular / platform-server'; import {AppComponent} из './app.component'; @NgModule ({объявлений: [], импорт: [// Убедитесь, что строка соответствует BrowserModule.withServerTransition ({appId: 'my-app-id'}), ServerModule, AppModule], поставщики: [], начальная загрузка: [AppComponent ]}) class ServerAppModule {}

Создание второй точки входа Обычно наше угловое приложение имеет только одну точку входа. То есть там, где вызывается метод начальной загрузки. В проекте cli этот вызов находится в файле main.ts в каталоге src. Мы можем оставить этот файл как есть. Это будет отправной точкой для нашей версии браузера.

Чтобы создать точку входа для нашей версии сервера, просто создайте другой файл прямо рядом с main.ts. Давайте назовем это server.main.ts. Содержание этого файла действительно просто. Просто экспортируйте наш серверный модуль туда.

экспортировать {ServerAppModule} из './app/server.app.module'

Рассказывая угловому компилятору о наших модулях ввода, чтобы это работало, мы также должны сообщить угловому компилятору, какими являются наши модули ввода. Для этого нам понадобятся два отдельных файла tsconfig.json, которые находятся в каталоге приложения src. По умолчанию cli генерирует здесь файл с именем tsconfig.app.json. Просто переименуйте его в tsconfig.browser.json. Просто чтобы прояснить ситуацию. Кроме того, создайте еще один файл с именем tsconfig.server.json.

Бот-файлы действительно просты. Вот как они выглядят:

src / tsconfig.browser.json {"extends": "../tsconfig.json", "angularCompilerOptions": {"entryModule": "./app/browser.app.module#BrowserAppModule"}, "exclude": [ "test.ts", "** / *. spec.ts"]} {"extends": "../tsconfig.json", "angularCompilerOptions": {"entryModule": "./app/server.app. module # ServerAppModule "}," exclude ": []}

В этот момент вы, возможно, заметили, что нужно настроить много шаблонов. Но мы еще не совсем закончили ...

Создание второго приложения для CLI

Последнее, что нам нужно сделать, это отредактировать angular-cli.json. Нам нужно сообщить CLI обо всех внесенных нами изменениях, чтобы он работал правильно. Кроме того, мы собираемся создать второй профиль для комплекта серверов. Затем cli генерирует этот пакет, содержащий только тот код, который нам требуется на сервере для рендеринга.

Короче говоря, вот как должен выглядеть раздел «apps» в angular-cli.json.

"apps": [{"root": "src", "outDir": "dist", "assets": ["assets", "favicon.ico"], "index": "index.html", "main ":" main.ts "," polyfills ":" polyfills.ts "," test ":" test.ts "," tsconfig ":" tsconfig.browser.json "," testTsconfig ":" tsconfig.spec.json "," prefix ":" app "," styles ": [" styles.css "]," scripts ": []," environmentSource ":" environment / environment.ts "," Environment ": {" dev ": "environment / environment.ts", "prod": "environment / environment.prod.ts"}}, {"root": "src", "outDir": "dist-server", "assets": ["assets "," favicon.ico "]," index ":" index.html "," main ":" server.main.ts "," platform ":" server "," polyfills ":" polyfills.ts "," test ":" test.ts "," tsconfig ":" tsconfig.server.json "," testTsconfig ":" tsconfig.spec.json "," prefix ":" app "," styles ": [" styles.css "]," scripts ": []," environmentSource ":" environment / environment.ts "," environment ": {" dev ":" environment / environment.ts "," prod ":" environment / env ironment.prod.ts "}}],

Затем позвольте CLI создавать наши пакеты. Мы можем сделать это, используя следующие команды одну за другой.

Клиентский пакет:

Серверный комплект:

Корневой каталог ваших приложений теперь должен содержать папку «dist» и «dist-server».

Далее мы собираемся использовать эти файлы с нашим сервером динамического рендеринга.

Далее мы собираемся использовать эти файлы с нашим сервером динамического рендеринга

Рендеринг на стороне сервера

Посмотрите:

Теперь, когда мы настроили наше угловое приложение, нам нужен сервер, чтобы фактически отобразить приложение. В этой главе мы создадим сервер node.js для рендеринга нашего приложения.

Настройка сервера динамического рендеринга

Для рендеринга на стороне сервера мы будем использовать внешний пакет, как я упоминал ранее. Этот пакет называется @ Nguniversal / экспресс-двигатель , Чтобы установить его, используйте одну из следующих команд.

@ Nguniversal / экспресс-двигатель

пряжа add @ nguniversal / express-engine npm install @ nguniversal / express-engine --save

Конечно, мы также требуем экспресс сам.

экспресс

пряжа добавить экспресс npm установить экспресс --save

Создание сервера Node.js

Чтобы создать наш сервер, просто создайте новый файл с именем server.js в корневом каталоге приложения. После этого нам нужно несколько модулей.

require ('zone.js / dist / zone-node') const express = require ('express') const ngExpressEngine = require ('@ nguniversal / express-engine / modules / express-engine'). ngExpressEngine const fs = require ('fs')

Далее нам нужно импортировать файл main. {Hash} .bundle.js из нашего каталога dist-server, созданного angular-cli. Но есть проблема: поскольку имя файла содержит хеш файла, имя файла меняется при каждой новой сборке (если что-то меняется). Одним из вариантов решения этой проблемы было бы использование флага «output-hashes none» angular-cli. Таким образом, хэш не добавляется к имени файла.

ng build --prod --app 1 - output-hashes none

Если вы хотите сохранить хеш, вы также можете сделать это:

var files try {files = fs. readdirSync (`$ {process. cwd ()} / dist-server`)} catch (error) {console. ошибка (ошибка)} var mainFiles = files. фильтр (файл => файл. startWith ('main')) var split = mainFiles [0]. split ('.') var hash = '' if (split .length> 3) hash = split [1] + '.' var {ServerAppModuleNgFactory, LAZY_MODULE_MAP,} = require (`./dist-server/main. $ {hash} bundle`)

Затем мы создаем приложение Express, вызывая express ().

После этого создайте и укажите механизм просмотра. Для этого мы используем импортированный и установленный ранее ngExpressEngine.

приложение движок (приложение "html", ngExpressEngine ({bootstrap: ServerAppModuleNgFactory, поставщики: [поставщик],})). приложение set ('view engine', 'html'). set ('views', __dirname)

Мы также должны обслуживать наши статические угловые файлы. Для этого мы добавляем в приложение dist и папку assets.

приложение использовать (express. static (__dirname + '/ assets', {index: false})) приложение. использовать (express. static (__dirname + '/ dist', {index: false}))

Затем нам нужно установить маршрут по умолчанию, который вызывает механизм представления ngExpress.

приложение get ('/ *', (req, res) => {console. time (`GET: $ {req .originalUrl}`) res. render ('./dist/index', {req: req, res: res ,}) console. timeEnd (`GET: $ {req .originalUrl}`)})

Наконец, запустите приложение, позвонив:

приложение слушай (процесс .env .PORT || 8080, () => {})

Настройка статического рендерера

Как мы узнали ранее, при обслуживании статических файлов HTML не содержит ссылок на скрипты для загрузки угловой структуры. Все, что нам нужно сделать, чтобы предотвратить загрузку всего фреймворка, это исключить ссылки на скрипты из нашего index.html. Для этого просто используйте index.html в нашей папке src вместо папки dist, так как она не содержит этих ссылок.

приложение get ('/ *', (req, res) => {console. time (`GET: $ {req .originalUrl}`) res. render ('./src/index', {req: req, res: res ,}) console. timeEnd (`GET: $ {req .originalUrl}`)})

Теперь мы обслуживаем полностью статичные файлы, которые содержат только HTML и соответствующие таблицы стилей. В зависимости от варианта использования ваших приложений может иметь смысл предоставлять эти статические файлы только вашим клиентам. Если ваше приложение не содержит необычных функций JavaScript, например, блог, вы можете значительно повысить производительность. Не обслуживая угловой код JavaScript, вы обычно сохраняете около 100 КБ сжатых данных. Большое приложение может легко пойти выше этого.

С другой стороны, если вам все равно не нужен JavaScript, почему вы выбрали JavaScript-фреймворк? Ну, может быть, это потому, что вы хотели повторно использовать свои навыки или просто изучать английский язык самостоятельно. Это то, что я сделал с этим блогом. Речь идет не только о угловых, но и написано в угловых. Все, что я говорю, это то, что вы должны тщательно выбирать свои инструменты ...

Все, что я говорю, это то, что вы должны тщательно выбирать свои инструменты

Не так давно ленивая загрузка была невозможна с угловым универсалом. К счастью, универсальная команда недавно опубликовала пакет, который включает эту функцию.

Этот пакет называется @ nguniversal / module-map-ngfactory-loader. Что он делает, так это создает карту всех лениво загруженных модулей и их маршрутов.

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

Это может показаться немного сложным, но не волнуйтесь. Тяжелая работа для нас уже проделана.

Все, что нам нужно сделать, это установить этот пакет и добавить несколько строк кода в наше приложение.

Примечание: я предполагаю, что у вас уже есть угловое приложение, которое использует отложенную загрузку. Если вы не знаете, как вы можете использовать ленивую загрузку, вы должны проверить это отличная статья от rangle.io о лениво загружаемых модулях ,

Итак, начнем!

Настроить

Как я уже упоминал ранее, нам нужно установить пакет @ nguniversal / module-map-ngfactory-loader для продолжения. Идите вперед и установите его, используя ваш любимый менеджер пакетов.

пряжа add @ nguniversal / module-map-ngfactory-loader npm install @ nguniversal / module-map-ngfactory-loader --save

Для правильной работы в пакете предусмотрен угловой модуль, который необходимо импортировать в наш серверный модуль приложения.

src / app / server.app.module.ts import {ModuleMapLoaderModule} из '@ nguniversal / module-map-ngfactory-loader'

После этого ваш серверный модуль приложения должен выглядеть примерно так:

src / app / server.app.module.ts import {AppModule} из './app.module' import {BrowserModule} из '@ angular / platform-browser' import {NgModule} из '@ angular / core' import {ServerModule } из '@ angular / platform-server' import {ModuleMapLoaderModule} из '@ nguniversal / module-map-ngfactory-loader' import {AppComponent} из './app.component' @ NgModule ({объявления: [], импорт: [BrowserModule. WithServerTransition ({appId: 'my-app-id',}), ServerModule, AppModule, ModuleMapLoaderModule,], поставщики: [], начальная загрузка: [AppComponent],}) class ServerAppModule {}

Как только это будет сделано, мы теперь должны немного изменить наш сервер.

Настройка сервера для поддержки отложенной загрузки

На стороне сервера нам также необходимо импортировать пакет @ nguniversal / module-map-ngfactory-loader. Точнее, нам нужен метод с именем provideModuleMap (). Чтобы получить этот метод, мы можем просто потребовать его из пакета.

const {provideModuleMap} = require ('@ nguniversal / module-map-ngfactory-loader')

Кроме того, нам нужно импортировать карту модуля, которую создало для нас наше угловое приложение. Для этого нам нужно это из нашего углового комплекта сервера.

const {ServerAppModuleNgFactory, LAZY_MODULE_MAP,} = require (`. / dist-server / main.bundle`)

Примечание: я использовал флаг -output-hashes none для angular-cli при создании этого пакета, чтобы удалить хеш из имени файла.

Далее мы вызываем метод provideModuleMap () и передаем ему карту модулей.

const provider = provideModuleMap (LAZY_MODULE_MAP)

У нас есть провайдер, которого мы можем передать ngExpressEngine следующим образом:

приложение engine ('html', ngExpressEngine ({bootstrap: ServerAppModuleNgFactory, провайдеры: [поставщик],}))

Вот и все. Теперь наше угловое универсальное приложение на стороне сервера знает обо всех маршрутах. Ленивый или нет.

Легко не так ли? Теперь, для вашего удобства, вот снова полное приложение server.js. Опять же, используя флаг «output-hashes none» angular-cli следующим образом:

ng build --prod --app 1 - output-hashes none // Angular требует Zone.js require ('zone.js / dist / zone-node'); const express = require ('express'); const ngExpressEngine = require ('@ nguniversal / express-engine'). ngExpressEngine; const {ServerAppModuleNgFactory, LAZY_MODULE_MAP} = require (`. / dist-server / main.bundle`); const app = express (); const {provideModuleMap} = require ('@ nguniversal / module-map-ngfactory-loader'); const provider = provideModuleMap (LAZY_MODULE_MAP); app.engine ('html', ngExpressEngine ({bootstrap: ServerAppModuleNgFactory, поставщики: [поставщик]})); app.set ('view engine', 'html'); app.set ('views', __dirname); app.use (express.static (__dirname + '/ assets', {index: false})); app.use (express.static (__dirname + '/ dist', {index: false})); app.get ('/ *', (req, res) => {console.time (`GET: $ {req.originalUrl}`); res.render ('./ dist / index', {req: req, res: res}); console.timeEnd (`GET: $ {req.originalUrl}`);}); app.listen (process.env.PORT || 8080, () => {});

PORT || 8080, () => {});

API Angular Transfer State (только Angular 5)

Angular 5 добавил API передачи состояния в угловой пакет. Это позволяет нам отправлять информацию с сервера, который представляет наше приложение, клиенту. Почему это полезно?

Наиболее распространенное приложение для передачи состояния клиенту - когда ваше приложение делает какой-либо HTTP-запрос, чтобы заполнить ваше приложение контентом.

Обычно, когда мы используем Angular Universal, API, который доставляет контент, попадает дважды. Один раз, когда сервер рендерит страницу, и другой раз, когда приложение загружается.

Такое поведение не только приводит к ненужной загрузке сервера, но также заставляет ваше приложение перезагрузить и повторно оценить страницу и загруженный контент. Это может вызвать очень разрушительный эффект мерцания в вашем приложении.

Конечно, выполнение дополнительного запроса также добавляет задержку в виде задержки к времени загрузки вашего приложения. Это может быть существенным фактором, если угловое приложение загружается на мобильные устройства.

Но это не должно быть все о HTTP-запросах. Может быть, у вас есть серьезные расчеты, чтобы сделать. Не будет ли это пустой тратой, если вам нужно будет рассчитать это дважды?

Но как мы можем улучшить это?

Используя API состояния передачи, мы можем дать команду серверу рендеринга включить загруженную / вычисленную информацию в сериализованной форме в вывод рендеринга. Таким образом, мы можем повторно использовать информацию, которую сервер все равно использовал.

Поскольку мы получаем все это в одном HTTP-ответе, мы также сохраняем задержку отправки другого запроса данных.

Реализация API состояния передачи

Добавить API состояния передачи в ваше приложение довольно просто. Все, что нам нужно сделать, это добавить Browser / Server-TranferStateModule в соответствующий модуль, и мы готовы к работе.

Для этого нам нужно добавить BrowserTransferStateModule в BrowserAppModule и ServerTransferStateModule в ServerAppModule.

src / app / browser.app.module.ts import {AppModule} из «./app.module» import {BrowserModule, BrowserTransferStateModule,} из «@ angular / platform-browser» import {NgModule} из «@ angular / core» import {AppComponent} из './app.component' @ NgModule ({объявлений: [], импорт: [BrowserModule. withServerTransition ({appId: 'my-app-id',}), BrowserTransferStateModule, AppModule,], провайдеры: [], начальная загрузка: [AppComponent],}) класс BrowserAppModule {}

И то же самое для сервера ...

src / app / server.app.module.ts import {AppModule} из './app.module' import {BrowserModule} из '@ angular / platform-browser' import {NgModule} из '@ angular / core' import {ServerModule , ServerTransferStateModule,} из '@ angular / platform-server' import {ModuleMapLoaderModule} из '@ nguniversal / module-map-ngfactory-loader' import {AppComponent} из './app.component' @ NgModule ({декларации: [] , импортирует: [BrowserModule. withServerTransition ({appId: 'my-app-id',}), ServerModule, AppModule, ModuleMapLoaderModule, ServerTransferStateModule,], поставщики: [], bootstrap: [AppComponent],}) класс ServerAppModule {}

Использование API Transfer State

Теперь, когда мы все настроили, мы можем использовать API состояния передачи, запрашивая экземпляр службы через внедрение зависимости , Для этого примера мы используем компонент с именем post.component.

Во-первых, мы запрашиваем службу состояния передачи внутри конструктора компонента. Поскольку мы, вероятно, также хотим знать, работаем ли мы в браузере или на сервере, мы также запрашиваем текущий PLATFORM_ID.

src / app / post / post.component.ts private isServer: логический; конструктор (личное tstate: TransferState, @ Inject (PLATFORM_ID) platformId) {this. isServer = isPlatformServer (platformId); }

TS-API можно рассматривать как некий контейнер хранения, из которого мы можем получить или установить значения. Чтобы достичь нашей цели, мы хотим вставить значения в контейнер, когда мы находимся на сервере, и извлечь их в браузере.

Каждое значение может быть доступно через ключ. Чтобы создать, получить или установить значение для контейнера, нам действительно нужен этот ключ. Этот ключ является не просто строкой, к которой мы привыкли в среде JavaScript, а экземпляром класса StateKey.

Чтобы создать такой StateKey, мы можем вызвать метод makeStateKey <> (), предоставляемый платформой.

Давайте создадим ключ для нашего так называемого результата. В реальном сценарии вы бы назвали этот ключ в соответствии со значением, к которому он может получить доступ (например, POST_KEY). Обратите внимание, что метод строго типизирован к типу значения. В нашем случае мы хотим передать строку.

src / app / post / post.component.ts import {TransferState, makeStateKey} из '@ angular / platform-browser' const RESULT_KEY = makeStateKey <string> ('result')

После этого мы можем использовать ключ, чтобы получить значение, если мы находимся в браузере. На сервере мы используем обратный вызов onSerialize (), чтобы вернуть значение для ключа. Таким образом, мы можем установить значение.

src / app / post / post.component.ts ngOnInit () {if (this. tstate. hasKey (RESULT_KEY)) {this. результат = это. состояние get (RESULT_KEY, ''); } еще {это. result = 'Я создан в браузере!' ; } этот . состояние onSerialize (RESULT_KEY, () => {return 'Я создан на сервере!';}); }

Просто не так ли?

Хотя приведенное выше решение является полностью действительным, оно может быть не самым очевидным решением. Чтобы было более понятно, что выполняется на сервере, мы можем использовать наш флаг isServer и метод set API.

src / app / post / post.component.ts ngOnInit () {if (this. tstate. hasKey (RESULT_KEY)) {this. результат = это. состояние get (RESULT_KEY, ''); } иначе если (это. isServer) {это. состояние set (RESULT_KEY, «Я создан на сервере!»); } еще {это. result = 'Я создан в браузере!' ; }}

Вот и все. Теперь мы знаем, как передать любое значение (я) с сервера рендеринга клиенту! Вот полный PostComponent:

src / app / post / post.component.ts import {Component, OnInit, PLATFORM_ID, Inject} из '@ angular / core' import {TransferState, makeStateKey} из '@ angular / platform-browser' import {isPlatformServer} из '@ angular / common 'const RESULT_KEY = makeStateKey <string> (' result ') @ Component ({selector:' app-post ', templateUrl:' ./post.component.html ', styleUrls: [' ./post.component. css '],}) класс PostComponent реализует OnInit {открытый результат private isServer: логический конструктор (private tstate: TransferState, @ Inject (PLATFORM_ID) platformId) {this. isServer = isPlatformServer (platformId)} ngOnInit () {if (this. tstate. hasKey (RESULT_KEY)) {this. результат = это. состояние get (RESULT_KEY, '')} else if (this. isServer) {this. состояние set (RESULT_KEY, «Я создан на сервере!»)} else {this. result = 'Я создан в браузере!' }}}

Заключение

В этой статье мы узнали, как настроить проект Angular Universal. что такое рендеринг на стороне сервера и почему его следует использовать для улучшения взаимодействия с пользователем. Мы также пошагово создали приложение с самого начала

Надеюсь, вам понравилась эта статья. Если вы это сделали, нажмите эту кнопку ниже и поделитесь ею с друзьями и коллегами!

Никогда не пропустите пост, подписавшись на меня в твиттере @malcoded ,

Похожие

SEO
Добро пожаловать в этот блог, я Саддам Гозали, который немного объяснит SEO это?. Поисковая оптимизация, которая обычно сокращается SEO Это попытка сделать блог, который направлен на увеличение объема трафика через
Как
... на Макберни романа Стефана Цвейга фокусируется на том, что такое Унгедулд де Герценс (буквально «нетерпение сердца»). Это новое совместное совместное производство от Саймона МакБерни основано на романе Стефана Цвейга «Унгедуль де Герценс». Больше... Исторические европейские боевые искусства (HEMA) относятся
Что такое время загрузки страницы?
Время загрузки страницы - это время, необходимое для загрузки и отображения всего содержимого веб-страницы в окне браузера (измеряется в секундах). Время загрузки страницы - это показатель веб-производительности, который напрямую влияет на вовлеченность
Что такое локальный SEO и как его оптимизировать?
Вполне возможно, что мы не раз слышали это о «локальном SEO», но в действительности мы не знаем, к чему он относится или чем он отличается от остальных стратегий позиционирования. Что такое локальный SEO? Местное SEO , собственно говоря, это позиционирование сайта локально. Ну, что это значит? Это зависит от географического местоположения пользователя, то есть это методы позиционирования, которые используются, когда вы хотите предоставить видимость сети
Что такое SEO и почему это так важно?
SEO это аббревиатура для области онлайн-маркетинга, которую мы на немецком языке Поисковая оптимизация звоните. Оригинальное название происходит от английской поисковой оптимизации, кратко SEO. Википедия определяет поисковую оптимизацию следующим образом: «Поисковая оптимизация или SEO (поисковая оптимизация) относится к мерам, которые служат для того, чтобы сайты с органическим рейтингом в поисковых системах
Что такое SEO компания и как работает SEO?
Что такое SEO компания? К настоящему времени вы, наверное, слышали о преимуществах SEO и о том, почему каждый бизнес нуждается в SEO. (Если у вас нет, проверьте наш пост об этом здесь .) Но вам все еще может быть интересно, как ваш бизнес может извлечь выгоду из SEO, если у вас нет профессионала SEO в штате. SEO может стать немного сложным, особенно если вы новичок в цифровом маркетинге. Если вы
SEO услуги
... нанная компания интернет-маркетинга предлагает вам индивидуальные услуги SEO, которые помогают вашему сайту достичь высокого рейтинга в поисковых системах. SEO это все о создании безошибочного сайта и позиционировании вашего сайта для поисковых систем. Мы гарантируем, что все основные поисковые системы, включая Google и Bing, правильно индексируют ваш сайт. Наши методы SEO помогают вам продавать онлайн, независимо от ваших технических возможностей, улучшают посещаемость вашего
На странице SEO против SEO страницы
В кругах цифрового маркетинга всегда было сражение, какой тип поисковой оптимизации лучше: на странице SEO или вне страницы SEO? источник Проще говоря, на странице SEO основное внимание уделяется предоставлению высококачественного контента, оптимизации этого контента с помощью целевых ключевых слов и фраз, а также предоставлению карты сайта и метатегов, которые
SEO против SEM (PPC): что лучше?
Разве вы не ненавидите, когда кто-то отвечает на вопрос «Это зависит»? Я обещаю, что не буду делать этого с вами в этом посте, в котором рассматривается классический вопрос, какую сторону бегемота Google Search решать: обычную или платную. Вопрос на самом деле очень похож на другой вековой вопрос о домовладении: лучше арендовать
Сассекс SEO
Мы быстро стали технологически ориентированным миром. Многие из нас не могут оставить свои смартфоны дома, потому что нам просто нужно проверить нашу электронную почту или посмотреть последние сообщения на нашей любимой социальной сети. Люди используют поисковые системы, чтобы находить информацию точно так же, как они привыкли зависеть от местных Желтых страниц. Из-за
SEO Доктор
Если ваш сайт начал классифицироваться по низким позициям или был дискредитирован Google, мы поможем

Комментарии

Свернуть, Обсудить, Обсудить, Обсудить, Обсудить, Обсудить, Приобрести Свернуть » Что это такое, что вы думаете, что вы думаете, что вы думаете?
Свернуть, Обсудить, Обсудить, Обсудить, Обсудить, Обсудить, Приобрести Свернуть » Что это такое, что вы думаете, что вы думаете, что вы думаете? Р'РїРμСЂРμРґРμР »РμРЅР ° Р» РμРЅР ° Свернуть, Свернуть, Свернуть, Свернуть, Свернуть, Свернуть, Свернуть, Свернуть, Свернуть , Москва, Россия, Россия, Россия, Россия, США. Возбуждаю, обдумываю, оберегаю, оберегаю, обдумываю, ·,,,, ЊР · ·ѕѕ С С С "С .... ....μ‡ .... ....‡ .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... ....
SEO не секрет, это требует напряженной работы и самоотверженности, которая является причиной, почему вы не сделаете это самостоятельно и посмотреть на работу других делать это за вас, не так ли?
SEO не секрет, это требует напряженной работы и самоотверженности, которая является причиной, почему вы не сделаете это самостоятельно и посмотреть на работу других делать это за вас, не так ли? Ваша SEO компания должна объяснить вам: - Как они планируют улучшить ваш рейтинг - Какие корректировки они внесут в ваш сайт - Как они планируют настроить вашу онлайн маркетинговую кампанию для достижения лучших результатов
Это не большое дело, но когда вы можете сэкономить полчаса, выполняя это с плагином и не думая об этом, почему бы вам не сделать это?
Это не большое дело, но когда вы можете сэкономить полчаса, выполняя это с плагином и не думая об этом, почему бы вам не сделать это? Многоузловое Если вы работаете более чем на одном сайте, вы можете установить мультисайт через WordPress. Таким образом, вы можете легко управлять всеми своими сайтами на одной панели, и вам не нужно постоянно переключаться. Yoast совместим с несколькими сайтами, поэтому вы можете оптимизировать все свои дочерние сайты одновременно.
Вы слышали, что вам нужно «заниматься SEO», но вы не представляете, что это за животное?
Вы слышали, что вам нужно «заниматься SEO», но вы не представляете, что это за животное? Вы хотели бы, чтобы на вас ссылались, не потратив целое состояние? Есть только одна книга, SEO Google: руководство пользователя для начинающих в SEO . Написанный Оливье Андрие, одним из знаменитостей во французской «сцене» SEO, SEO Google: руководство пользователя предлагает объяснить основы дисциплины . Программа заманчива! Это может
Но мы живем в очень конкурентном мире, и если вы не можете сосать сахарный тростник и свистеть одновременно, это не на рынке, не так ли?
Но мы живем в очень конкурентном мире, и если вы не можете сосать сахарный тростник и свистеть одновременно, это не на рынке, не так ли? Это также пришло в мир SEO, и профессионалы начали приспосабливаться к новым тенденциям. Они начали согласовывать стратегии: контент-маркетинга, входящего маркетинга, маркетинга, копирайтинга и т. Д. Давайте рассмотрим некоторые стратегии, обычно применяемые SEO-консультантами, которые НЕ являются основными навыками специалистов
Например, почему вы используете веб-тему когда вы можете использовать только некоторый опыт SEO, чтобы вы могли максимально использовать благополучие своих компаний?
Но мы живем в очень конкурентном мире, и если вы не можете сосать сахарный тростник и свистеть одновременно, это не на рынке, не так ли? Это также пришло в мир SEO, и профессионалы начали приспосабливаться к новым тенденциям. Они начали согласовывать стратегии: контент-маркетинга, входящего маркетинга, маркетинга, копирайтинга и т. Д. Давайте рассмотрим некоторые стратегии, обычно применяемые SEO-консультантами, которые НЕ являются основными навыками специалистов
Итак, как владелец бизнеса, как вы убедитесь, что ваша команда / команда SEO действительно делает то, что они должны делать?
Итак, как владелец бизнеса, как вы убедитесь, что ваша команда / команда SEO действительно делает то, что они должны делать? Как вы можете быть уверены, что они не будут делать то, что может буквально разрушить ваш бизнес в будущем? По моему опыту, самое лучшее, что вы можете сделать, - это заказать профессиональный аудит сайта SEO. Всесторонний SEO-аудит, выполненный настоящим профессионалом, охватит весь ваш сайт с точки зрения поисковой системы и может сказать вам, что было сделано
Конечно, спам - это то, что люди делают для повышения своего рейтинга, но знаете ли вы, что вы тоже можете это делать?
Конечно, спам - это то, что люди делают для повышения своего рейтинга, но знаете ли вы, что вы тоже можете это делать? Это известно как непреднамеренный спам, который происходит без того, чтобы вы пытались это сделать. Но Google все равно воспримет это как обычный случай рассылки спама и понизит ваш рейтинг. Так как же избежать этого непреднамеренного спама? При устранении неполадок, связанных с ошибками в локальном SEO-рейтинге для финансовых веб-сайтов, постарайтесь определить, где
Что вы действительно хотите как владелец ресторана, так это не туристы, которых вы больше никогда не увидите, а счастливые постоянные клиенты, верно?
Что вы действительно хотите как владелец ресторана, так это не туристы, которых вы больше никогда не увидите, а счастливые постоянные клиенты, верно? Люди, которые любят возвращаться. Они могут даже привести других и рассказать своим друзьям о моем ресторане. Вот почему я убежден, что вы можете забыть все отличные советы по SEO. Мой первый совет будет: « Танцуй, пиши, как никто не смотрит » (Я думаю, что совет
Если вы не собираетесь инвестировать в SEO-сервисы на таких сайтах, как Fiverr, куда еще вы должны инвестировать свои деньги в SEO?
Если вы не собираетесь инвестировать в SEO-сервисы на таких сайтах, как Fiverr, куда еще вы должны инвестировать свои деньги в SEO? Это отличный вопрос, и ответ таков: инвестируйте в ПРАВИЛЬНЫЕ инструменты SEO. Если у вас есть доступ к премиальным инструментам SEO, таким как SEMrush, вы можете легко управлять всеми действиями SEO своего сайта, включая аудит сайта, поиск отличных ключевых слов, анализ обратных ссылок и так далее. Если вам интересно, какие полезные
2. Вопрос в том, что если обычные расходы на SEO отодвигаются и перенаправляются на другие маркетинговые каналы, разве это не говорит о том, что ваш сайт не генерирует мудрости с первой позиции?
2. Вопрос в том, что если обычные расходы на SEO отодвигаются и перенаправляются на другие маркетинговые каналы, разве это не говорит о том, что ваш сайт не генерирует мудрости с первой позиции? Мудрость прогресса и успешных продаж, в той мере, в которой это устраняет затраты для SEO? 3. Разве более продвинутая компания на самом деле не увеличивает свои затраты на SEO, чтобы они оставались стабильными на верхних позициях и рассматривали своих конкурентов так же высокомерно, как признак

Что такое Angular Universal?
Что такое Angular Universal?
Подождите?
Почему ты говоришь в прошедшем времени?
Но как это вообще работает?
Почему вы должны рендерить на сервере?
Угловая универсальная: серебряная пуля?
Так почему же это недостаток?
Какой смысл иметь, например, Google Analytics на сервере?
С другой стороны, если вам все равно не нужен JavaScript, почему вы выбрали JavaScript-фреймворк?