6 лучших практик и профессиональных советов на тему использования Angular CLI

6 лучших практик и профессиональных советов на тему использования Angular CLI

От автора: разрабатывать приложения с помощью Angular CLI одно удовольствие! Команда Angular дала нам замечательный CLI с поддержкой большей части функций, необходимых для любого серьезного проекта. Стандартизированная структура проекта со всеми возможностями по тестировке (юнит и e2e тесты), достройка кода, степени продакшн билда с возможностью настройки окружения. Мечта становится явью, а вы экономите часы над новыми проектами. Спасибо, команда Angular!

Angular CLI замечательно работает прямо из коробки, однако в него можно внести несколько потенциальных улучшений, следуя лучшим практикам, чтобы наши проекты стали еще лучше!

Что мы будем изучать

Лучшие практики на модулях Core, Shared и Feature с ленивой загрузкой

Использование алиасов для приложения и папок окружения для более чистого импорта

Зачем и как использовать Sass и Angular Material

Практический курс по созданию веб-приложения на Angular4

Станьте профессиональным веб-разработчиком, создавая востребованные веб-приложения на Angular4.

Узнать подробнее

Как создать хороший продакшн билд

Как отказаться от PhantomJS и перейти на Headless Chrome (тестирование)

Как выпускать проект с автоматически генерируемым логом изменений и автоматическим исправлением версии

1. Немного архитектуры

«Хорошо, мы сгенерировали новый проект с помощью Angular CLI, что дальше? Нужно ли продолжать генерировать сервисы и компоненты в случайные папки? Как структурировать проект?»

Хорошо разделить наше приложением на, как минимум, три разных модуля —  Core, Shared и Feature (нам может понадобится более одного модуля feature).

CoreModule

Здесь необходимо реализовать все сервисы, которые должны иметь только один экземпляр в приложении (singleton сервисы). Типичные примеры – сервисы authentication и user. Разберем пример CoreModule.

/* 3rd party libraries */
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';

/* our own custom services  */
import { SomeSingletonService } from './some-singleton/some-singleton.service';

@NgModule({
  imports: [
 /* 3rd party libraries */
 CommonModule,
 HttpClientModule,
  ],
  declarations: [],
  providers: [
 /* our own custom services  */
 SomeSingletonService
  ]
})
export class CoreModule {
  /* make sure CoreModule is imported only by one NgModule the AppModule */
  constructor (
 @Optional() @SkipSelf() parentModule: CoreModule
  ) {
 if (parentModule) {
 throw new Error('CoreModule is already loaded. Import only in AppModule');
 }
  }
}

SharedModule

Здесь необходимо реализовать все «тупые» компоненты и пайпы. Эти компоненты не импортируют и не вставляют сервисы из ядра или других функций в конструкторах. Они должны получать все данные через атрибуты в шаблоне использующего их компонента. Это все ведет к тому, что у SharedModule нет зависимостей с остальной частью приложения.

Идеальное место для импорта и реэкспорта компонентов Angular Material.

/* 3rd party libraries */
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule  } from '@angular/forms';
import { MdButtonModule } from '@angular/material';

/* our own custom components */
import { SomeCustomComponent } from './some-custom/some-custom.component';

@NgModule({
  imports: [
 /* angular stuff */
 CommonModule,
 FormsModule,

 /* 3rd party components */
 MdButtonModule,
  ],
  declarations: [
 SomeCustomComponent
  ],
  exports: [
 /* angular stuff */
 CommonModule,
 FormsModule,

 /* 3rd party components */
 MdButtonModule,

 /* our own custom components */
 SomeCustomComponent
  ]
})
export class SharedModule { }

Как подготовить структуру проекта с помощью Angular CLI

Модули Core и Shared можно генерировать сразу после создания нового проекта. Так мы подготовимся к генерации дополнительных компонентов и сервисов с самого начала.

Запустите команду ng generate module core. Затем создайте файл index.ts в папке core и реэкспортируйте CoreModule. Мы будем реэкспортировать публичные сервисы, которые должны быть доступны во всем приложении на протяжении всей разработки.

После можно сделать то же самое для модуля shared.

FeatureModule

Мы создадим модули feature под каждую независимую функцию нашего приложения. Модули Feature должны включать только импорт сервисы из CoreModule. Если feature модулю А нужно импортировать сервис из feature модуля В, перенесите этот сервис в ядро.

«Иногда нужны сервисы, доступные только в пару функций, и перемещать их в ядро нет смысла. В этом случае можно создать специальные общие функциональные модули, что будет описано далее в статье.»

«Главное правило – старайтесь создавать функции, чтобы они зависели только от сервисов CoreModule и компонентов SharedModule и не зависели от других функций.»

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

LazyLoading

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

2. Алиасы для приложения и окружения

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

Рассмотрим гипотетическую, но частую ситуацию Мы работаем с компонентом, который находится на 3 папки вглубь в функции А, и нам нужно импортировать сервис из ядра, которое хранится на 2 папки вглубь. Для этого нам понадобится импорт выражение типа import { SomeService } from ‘../../../core/subpackage1/subpackage2/some.service’. «Определенно, не самый чистый импорт…»

Что еще хуже – каждый раз, когда нам необходимо изменить расположение этих двух файлов, у нас будет ломаться импорт. Сравните это выражение с более коротким import { SomeService } from «@app/core». Лучше, правда?

Чтобы использовать алиасы, необходимо добавить свойства baseUrl и paths в файл tsconfig.json…

{
  "compilerOptions": {
 "...": "reduced for brevity",
 
 "baseUrl": "src",
 "paths": {
 "@app/*": ["app/*"],
 "@env/*": ["environments/*"]
 }
  }
}

Мы также добавим алиас @env, чтобы получать переменные окружения из любого места в приложении с помощью выражения import { environment } from «@env/environment». Оно будет работать на все заданное окружение, так как оно автоматически резолвит корректный файл окружения по флагу –env, передаваемому в команду ng build. Пути настроили, теперь можно импортировать окружение и сервисы…

/* 3rd party libraries */
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';

/* globally accessible app code (in every feature module) */
import { SomeSingletonService } from '@app/core';
import { environment } from '@env/environment';

/* localy accessible feature module code, always use relative path */
import { ExampleService } from './example.service';

@Component({
  /* ... */
})
export class ExampleComponent implements OnInit {
  constructor(
 private someSingletonService: SomeSingletonService,
 private exampleService: ExampleService
  ) {}
}

Вы могли заметить, что мы импортируем записи (типа SomeSingletonService) напрямую из @app/core, а не @app/core/some-package/some-singleton.service. Это возможно, благодаря реэкспорту всех публичных записей в главном файле index.ts. На пакет (папку) создаем один файл index.ts, выглядят они следующим образом…

export * from './core.module';
export * from './auth/auth.service';
export * from './user/user.service';
export * from './some-singleton-service/some-singleton.service';

В большинстве компонентов и сервисов конкретного функционального модуля будет нужен доступ к сервисам CoreModule и компонентам SharedModule. Иногда этого может быть недостаточно для решения определенных бизнес-кейсов, и нам будут нужны «общие функциональные модули», которые дают функционал для ограниченного поднабор других функциональных модулей.

В этом случае наш импорт будет следующим import { SomeService } from ‘@app/shared-feature’;. Как в ядре, shared-feature берется через алиас @app.

6 лучших практик и профессиональных советов на тему использования Angular CLI

3. Использование Sass

Sass – препроцессор стилей, добавляющий поддержку таких вещей, как переменные (несмотря на то, что в CSS они скоро и так появятся), функции, миксины…

Sass также требует использовать официальную библиотеку Angular Material Components с расширенными возможностями темизации. Можно с уверенностью предположить, что Sass – выбор по умолчанию для большинства проектов.

Для использования Sass необходимо генерировать наш проект через Angular CLI команду ng new с флагом —style scss. Команда задаст большую часть обязательных настроек. Единственно, что не добавляется по умолчанию — stylePreprocessorOptions с includePaths. Мы можем задать их сами с помощью обязательного корневого значения «./» b и необязательного «./themes».

{
  "apps": [
 {
 "...": "reduced for brevity",
 
 "stylePreprocessorOptions": {
 "includePaths": ["./", "./themes"]
 }
 }
  ]
}

Это поможет нашему редактору найти импортированные символы и улучшить опыт разработки с помощью автоподстановки кода переменных Angular Material и функций-утилит.

Практический курс по созданию веб-приложения на Angular4

Станьте профессиональным веб-разработчиком, создавая востребованные веб-приложения на Angular4.

Узнать подробнее

«При создании темы приложения Angular Material хорошим тоном считается выносить определения темы в отдельную папку themes, одна тема на файл.»

4. Билд prod

По умолчанию проект, сгенерированный через Angular CLI, идет с очень простым скриптом ng build. Чтобы сгенерировать производственные артефакты, нам нужно кое-что настроить.

Необходимо добавить «build:prod»: «ng build —target production —build-optimizer —vendor-chunk» в наши скрипты package.json.

Целевое производство

Это флаг, активирующий минификацию кода и множество полезных билд флагов по умолчанию. Эквивалент следующему…

—environment prod —используйте файл environment.prod.ts для переменных окружения

—aot – включает компиляцию Ahead-of-Time. В будущих версиях Angular CLI она будет включена по умолчанию, но сейчас ее нужно включать вручную

—output-hashing all – хэш сгенерированных файлов и добавление хэша в конец имени файла для облегчения перебора кэша браузера (любое изменение в контенте файла приведет к разнице хэшей, что вынудит браузер загрузить новую версию файла)

—extract-css true – извлекает все CSS в отдельный файл стилей

—sourcemaps false  — отключает генерацию source maps

—named-chunks false – отключает человекопонятные имена и использует вместо этого цифры

Другие полезные флаги

—build-optimizer – новая функция, которая уменьшает размер бандлов, но увеличивает время создания билдов. Используйте аккуратно! (также должна быть включена по умолчанию в будущем)

—vendor-chunk  — извлекает весь вендорный код (код библиотек) в отдельный кусок

Посмотрите официальные документации к другим доступным флагам, которые могут пригодиться в отдельном проекте.

5. Phantom JS мертв! Да здравствует Headless Chrome!

PhantomJS – хорошо известный браузер без оболочки, который дэ факто был РЕШЕНИЕМ для запуска frontend тестов на CI серверах и множестве машин.

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

6 лучших практик и профессиональных советов на тему использования Angular CLI

Из официальной документации«Headless Chrome доступен в Chrome 59. С его помощью можно запускать браузер Chrome на машинах без оболочки. По факту, можно запускать Chrome без Chrome! Он переносит все современные функции веб-платформы Chromium и рендер движка Blink в командную строку.»

«Круто! Как это использовать в проекте на Angular CLI?»

В команду теста необходимо добавить флаг —browser ChromeHeadless. В итоге получается «test»: «ng test —browser ChromeHeadless —single-run» и «watch»: «ng test —browser ChromeHeadless» в наших скриптах package.json. Довольно просто!

6. Использование стандартизированных сообщений о комитах и генератор автоматических логов изменений

Всегда приятно быстро узнать о новых функциях и фиксах багов интересующего нас проекта. «Давайте дадим нашим пользователям такую же возможность!»

Писать логи изменений вручную – крайне утомительная задача, подверженная ошибкам. Лучше автоматизировать этот процесс. Нам могут помочь множество инструментов, но давайте остановимся на standard-version.

Он автоматически генерирует и обновляет файл CHANGELOG.md со всеми комитами, следуя Conventional Commits specification, а также корректно объявляет новую версию проекта.

Обычный комит задает обязательный type, необязательный (scope):, после чего идет commit message. Также можно добавить необязательные body и footer, оба разделяются пустой строкой. Давайте посмотрим инструмент на практики. Рассмотрим пример полного сообщения о комите библиотеки ngx-model.

fix(dependency): multiple versions of rxjs in single project (TS90010)
BREAKING CHANGE: rxjs is now peerDependency instead of dependency
closes #1

Стандартная версия будет корректно удалять MAJOR версию проекта, так как присутствует ключевое слово BREAKING CHANGE в теле комита. Сгенерированный CHANGELOG.md будет выглядеть следующим образом…

6 лучших практик и профессиональных советов на тему использования Angular CLI

Красиво! Как использовать это в нашем проекте? Сначала необходимо установить npm install -D standard-version, чтобы сохранить его в devDependencies и добавить «release»: «standard-version» в наши скрипты package.json.

Также можно добавить git push и npm publish для автоматизации всего процесса. В этом случае команда выглядит так «release»: «standard-version && git push — follow-tags origin master && npm publish».

Обратите внимание, мы использовали &&, чтобы объединить команды. Команда зависит от платформы и работает только на UNIX системах (также на Windows с Cygwin, Gitbash и новой подсистеме Win10 для Linux).

Бонус: использование resource root (только Intellij IDEA, Webstorm)

Intellij IDEA не всегда находит все пути по умолчанию, из-за чего появляется много красных подчеркиваний, а также ломается автокомплитер кода. К счастью, решение простое. Просто выберите папку src и пометьте ее как Sources Root.

6 лучших практик и профессиональных советов на тему использования Angular CLI

Замечательно! Вы дошли до конца!

Надеюсь, эти советы и лучшие практики помогли вам.

Автор: Tomas Trajan

Источник: https://medium.com/

Редакция: Команда webformyself.

Практический курс по созданию веб-приложения на Angular4

Станьте профессиональным веб-разработчиком, создавая востребованные веб-приложения на Angular4.

Узнать подробнее
Самые свежие новости IT и веб-разработки на нашем Telegram-канале

Angular 4 с Нуля до Профи

Angular 4 - полное руководство для современной веб-разработки

Научиться

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree