Элегантная angular архитектура

Kate

Administrator
Команда форума
После нескольких лет проектирования и разработки различных приложений с полным стеком с нуля я замечаю, насколько важно с самого начала построить хорошую архитектуру для приложений angular. Хорошая архитектура может спасти нас от тяжелого рефакторинга, когда приложения становятся большими и сложными, поскольку все мы знаем, что владельцы продуктов никогда не перестанут добавлять новые функции в бэклоги :). Поэтому я хотел бы поделиться этой элегантной архитектурой Angular (V2 +), чтобы помочь новым разработчикам избежать обходных путей. С другой стороны, эта архитектура хорошо работает для быстрорастущих проектов, а также для хакатонов, где большое количество разработчиков angular могут работать вместе и в конце концов добиваться ожидаемых результатов.
Вы можете спросить меня, что такое «элегантная» архитектура?
Вот мои критерии:
· Четкая и понятная структура, позволяющая новому товарищу по команде быстрее подключиться к нашим проектам
· Отличная расширяемость, позволяющая добавлять новые функции, не касаясь каркаса
· Хорошая производительность без длинного загрузчика, вызывающая нетерпение пользователей
· Разумное время сборки и небольшой размер пакета
· Включая механизм имитации и тестирования
· Завершенные сценарии сборки для всех сред
Начнем с общего обзора:

1617289282066.png

Как видно из графиков выше, есть два типа модулей: активно загружаемые и отложенные. Итак, в чем разница между двумя модулями? По умолчанию все модули NgModules загружаются с нетерпением, что означает, что они загружаются, как только приложение загружается, даже если они нам не нужны немедленно. Как следствие, время загрузки страницы приветствия может быть очень долгим. Чтобы улучшить взаимодействие с пользователем, разработчикам настоятельно рекомендуется использовать метод отложенной загрузки. Этот метод может помочь разработчикам уменьшить начальный размер пакета и время загрузки. Для реализации обратитесь к https://angular.io/guide/lazy-loading-ngmodules.

Итак, что это за модули? Посмотрим по очереди :)
· Модуль приложения: точка входа, корневой модуль по умолчанию для приложения.
· Модуль маршрутизации приложений: корневой модуль маршрутизации
· Базовый модуль: модуль, в который мы помещаем все одноэлементные службы, о нем мы поговорим позже.
· Модуль авторизации: отвечает за авторизацию. Когда серверная часть отказывает пользователям в доступе, они будут перенаправлены на неавторизованную страницу. Как вы знаете, в этот модуль мы поместили знаменитую «Стражу». Если вы никогда не слышали о «Guard», следующая ссылка может помочь вам узнать о нем больше https://angular.io/api/router/CanActivate
· Модуль обработки ошибок: он содержит все страницы ошибок, кроме тех, которые уже существуют в модуле авторизации. Например, мы можем поместить наши настроенные 500 страниц с ошибками при сбое соединения на бэкэнд в модуле.
· Общий модуль: куда мы можем поместить все повторно используемые элементы. Подробнее об этом модуле мы также поговорим позже.
· Функциональный модуль и функциональный модуль: как следует из названия, функциональный модуль реализует конкретную функцию, которая состоит из нескольких страниц, сервисов функций и модуля маршрутизации.
Основной модуль
Основной модуль предназначен для одноэлементных служб, совместно используемых всем приложением. Что касается многоразовых сервисов, то их следует разместить в общем модуле. С другой стороны, для сервисов, используемых только одним функциональным модулем, лучшее место будет в самом функциональном модуле.
Итак, какие услуги являются одиночными?
· Все сервисы-перехватчики: например, http-перехватчик для перехвата сообщений об ошибках из серверной части.
· Служба загрузчика: не все используют конкретную службу для управления загрузчиком. Однако я думаю, что это лучшая идея. Служба одноэлементного загрузчика может избежать одновременного отображения нескольких загрузчиков. Мы можем просто передать сервис куда захотим!
· Сервис тостера: аналогичен сервису загрузчика.
· Служба конфигурации: она считывает конфигурацию из файла среды и дает нам правильный URL-адрес серверной части.
· Служба аналитики: вы можете добавить эту службу, если используете такие инструменты, как Google Analytics.
· Навигационная служба: для записи истории навигации пользователей.
Кроме того, основной модуль - это особый модуль, потому что мы должны гарантировать, что он импортируется в модуль приложения только один раз. Поэтому мы должны создать специальный конструктор с декораторами Optional и SkipSelf:

1617289789803.png


Мы знаем, что эти декораторы предназначены для внедрения зависимостей. Необязательный означает, что ничего страшного, если вводить нечего. Другими словами, инъекция будет успешной, даже если инжектор с именем parentModule не существует. SkipSelf означает пропуск самого себя, конструктор должен искать другой CoreModule, чем сам модуль.
При первом импорте CoreModule конструктор вызывается с нулевым parentModule, поэтому импорт будет успешным. Однако, если CoreModule импортируется во второй раз, поскольку CoreModule уже существует, будет выдана ошибка.
Вот как мы определяем, импортирован ли CoreModule в другой модуль. Это то, чего мы не хотим видеть в процессе импорта CoreModule.
Общий модуль
В отличие от основного модуля, общий модуль можно импортировать сколько угодно раз. В большом приложении у нас есть многоразовые каналы, компоненты, директивы и службы. Мы можем повторно использовать их, объявив их в общем модуле и импортировав общий модуль либо в функциональный модуль, либо иногда в корневой модуль.
Однако мы можем подумать, что элемент будет использоваться только одним функциональным модулем в начале реализации, поэтому мы напрямую объявляем его в функциональном модуле. Если позже мы захотим повторно использовать элемент в другом функциональном модуле, нам нужно будет переместить его в общий модуль.
Что, если мы хотим использовать один и тот же компонент в разных приложениях? Решением будет извлечение этого компонента в библиотеку angular. Что касается тонкого виджета, я предпочитаю делать его в React и импортировать через его ссылку CDN.
Лучшие практики
Прежде чем мы попрощаемся, я хочу поделиться тремя небольшими примерами передового опыта.
Первый - выбрать правильные зависимости. Например, если вы можете просто использовать канал формата даты или небольшой метод DIY, устанавливать moment.js не нужно. Вы не представляете, насколько велик moment.js, это будет катастрофа для размера пакета!
Второй - избегать использования собственных операций DOM или jQuery непосредственно в кодах angular. По мере того, как Angular становится все сильнее и сильнее, всегда есть эквивалентные решения Angular. При реализации модального окна вместо того, чтобы открывать или закрывать его с помощью селектора jQuery, я бы предпочел интегрировать NgbActiveModal из ng-bootstrap, его API предлагает нам все чистые операции https://ng-bootstrap.github.io/#/components/modal / api. Если вы хотите получить доступ к элементам DOM в компоненте, не забудьте декораторы @ViewChild и @ViewChildren.

И последнее, но не менее важное: необходима хорошая связь с серверной частью. Я заметил проблемы с производительностью после того, как присоединился к проекту в середине его разработки. Время загрузки страницы приветствия со списком продуктов очень велико. Поэтому решил проанализировать логи в консоли навигатора. Знаете что, я был шокирован размером ответов backend API. Он получил все свойства продуктов, которые нам не нужны для отображения на странице приветствия, но должны отображаться на странице сведений о продукте. Решение простое. В этом случае мы сделали две отдельные конечные точки в бэкэнде. Первый содержит только основную информацию о продуктах на странице приветствия; второй, с другой стороны, возвращает всю информацию о продукте с заданным идентификатором для страницы сведений о продукте. Поэтому, когда связь плохая, мы должны спросить себя, не извлекаем ли мы слишком много бесполезной информации из бэкэнда?
Конец

Перевод статьи с сайта https://medium.com/
 
Сверху