Pull to refresh

+10 правил чистого кода от Angular разработчика

Reading time4 min
Views12K
Привет, Хабр!

Сегодня хотел затронуть тему правильного кода в работе с Angular. Данные рекомендации сделают ваш код эффективнее в применении на практике, а так же позволят мне быть не таким требовательным к коду у junior'ов.

1. Избегайте логики в шаблонах

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

<p *ngIf="isShow"> Example </p>

public ngOnInit(): void {
    this.isShow = true;
}

2. «Безопасные» строки

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

private value: 'One' | 'Two';
if (isShow) { 
   value = 'One'; 
} else { 
   value = 'Two' 
}

Объявляя тип переменной таким образом, мы можем избежать ошибок при написании кода во время компиляции, а не во время его выполнения.

3. Правило длинных методов

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

4. Дублирование кода

Если у вас существует код, который повторяется в разных местах в проекте. Извлеките повторяющийся код в отдельный метод и используйте его вместо повторяющегося кода.

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

5. trackBy

Давайте разбавим список тонкостей работы с Angular.

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

<li *ngFor="let item of items; trackBy: trackByFn">{{ item }}</li>

trackByFn(index, item) {    
   return item.id; // уникальный идентификатор, соответствующий элементу
}

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

6. Подписка (Subscribe) в шаблоне

Обратите внимание на пример подписки на наблюдаемый компонент:

<p>{{ text }}</p>

blablaObservable
    .pipe(
       map(value => value.item),
       takeUntil(this._destroyed$)
     )
    .subscribe(item => this.text = item);

Теперь вы увидели как делать не надо. Не то чтобы я призывал вас жёстко следовать моим рекомендациям, просто зачастую разработчики не вникают что же происходит в их коде. Так почему же это плохо и как сделать хорошо? Дело в том, что мы рискуем получить случайный отказ от подписки на подписку в компоненте, что может привести к утечке памяти. Наиболее лучший вариант использовать подписку в самом шаблоне:

<p>{{ text$ | async }}</p>

this.text$ = blablaObservable
    .pipe(
       map(value => value.item)
     );

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

7. Ленивая загрузка

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

// app.routing.ts

{ 
  path: 'dashboard',
  loadChildren: 'lazy-load.module#DashboardModule' 
}

8. Подписка внутри подписки

Иногда вам могут потребоваться значения из более чем одного observable для выполнения действия. В этом случае избегайте подписки на один observable в блоке подписки другого observable. Вместо этого используйте соответствующие операторы цепочки. Операторы цепочек запускаются на observables от оператора перед ними. Некоторые операторы цепные, такие как withLatestFrom, combineLatest и т.д…

До:

oneObservable$.pipe(
   take(1)
)
.subscribe(oneValue => {
    twoObservable$.pipe(
        take(1)
    )
    .subscribe(twoValue => {
        console.log([oneValue, twoValue].join(', '));
    });
});

После:

oneObservable$.pipe(
    withLatestFrom(twoObservable$),
    first()
)
.subscribe(([oneValue, twoValue]) => {
    console.log([oneValue, twoValue].join(', '));
});

9. Кэширование

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

10. Дробление на многоразовые компоненты

Делите большие компоненты на более мелкие. Упрощайте такие компоненты и делайте их настолько тупыми, насколько это возможно, так как это заставит их работать в большем количестве сценариев. Создание такого компонента означает, что компонент не имеет в себе никакой специальной логики и работает исключительно на основании предоставленных ему входов и выходов. Как правило, последний потомок в дереве компонентов будет самым простым из всех. Делается это исходя из простоты использования таких компонентов, у таких компонентов меньше шансов получить ошибки. Так же, многоразовые компоненты уменьшают дублирование кода, что упрощает ведение и внесение изменений.

Хотите ли продолжение такой рубрики?
Tags:
Hubs:
-3
Comments2

Articles