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

Если пару лет назад шли вопросы о том, какой фреймворк выбрать, то сейчас все задаются вопросом: “Как оттуда выбраться”.  Давайте разберемся с тем как это произошло, и что стоит делать, чтобы не попасть в жернова фронтенд фреймворка.

Как всё начиналось

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

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

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

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

Как Angular захватил сердца разработчиков

Появившееся фреймворки и библиотеки того периода (dojo, Ext JS, Backbone.js, Ember.js, MooTools, jQuery, AngularJs, React) были плохо предназначены для больших, масштабируемых приложений.

Именно тогда, ребятам из Google пришла гениальная идея - сделать фронтенд похожим на бэкенд. Взяв в качестве основы TypeScript, который в свою очередь разработан одним из разработчиков С#, были реализованы современные паттерны и решения, в частности Dependency Injection, style encapsulation, web components, lazy loading, tree shaking, hmr, shadow dom и прочее.

Все это было названо Angular 2, который пришел на замену AngularJS. Подробная документация, реализация material, роутинг, style guides позволило привлечь огромное количество разработчиков в фронтенд.

Миграция с PHP на TypeScript стала обыденностью.

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

Почему разработчики выбирали Angular, а не React?

Ответ достаточно прост - он был не похож на большинство новомодных фреймворков.

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

  1. Строгая типизация с Typescript. Чем более типизирован язык, тем меньше ошибок может содержать код. Банальным примером может быть строгая проверка на NULL. Если соблюдать это правило с самого начала разработки, то это позволит избежать такого количества ошибок, что позволит сократить весь штат тестировщиков в компании, и переложить тестирование непосредственно на разработчика.

  2. RxJS. Если Promise стали глотком свежего воздуха по созданию асинхронных событий, то RxJS был сравни торнадо. Создание потоков данных, объединение, подмена и сокрытие, выполнение по условию - все это кардинально изменило подход к созданию асинхронных событий.

  3. Реализация внедрения зависимостей (Dependency Injection) стала ключом к началу перехода разработчиков из бэка во фронт. Упрощение управлением и созданием сервисов, позволило создавать разные инфраструктурные слои, что дало возможность структурировать JavaScript код. 

  4. Angular Router позволил взглянуть на шаблонизацию в новом ракурсе. Если раньше большинство шаблонизаторов имели простую и понятную, систему вложенности друг в друга, то Angular шагнул дальше и предоставил разработчикам мульти вложенность. Другими словами можно было разделить экран на несколько частей и сделать каждый элемент системы полноценным независимым юнитом со своей навигацией и роутингом, позволяя сохранять состояние каждого из таких компонентов в url.

  5. Angular Form раз и навсегда решили проблему с созданием и управлением формами. Реактивные формы, которые работали быстро, ожидаемо, имели множество состояний и валидаторов, заняли особое место в сердцах разработчиков. Создание кастомных контролов с помощью ControlValueAccessor обладали настолько сильным влиянием, что уже безнадежно приковывали разработчика к фреймворку.

  6. Схематики (Schematics) и Angular CLI дали возможность разработчику созданию шаблонов и генерации кода. Описав свои правила, можно было добиться невероятной скорости разработки.

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

Трудности работы Angular с SSR

Так как одной из главных зол фронтендера является SEO, ребята из Angular решили это очень просто - они просто не стали ничего делать.

Не путать с CEO (CTO) - к нему нет претензий, хотя он тоже может приносить проблемы.

Если взять и развернуть новый проект на Angular (на данный момент 13 версия), то вы не получите SEO из коробки. Для поддержки SEO вам необходимо настроить SSR, который в Angular представлен пакетом Universal.

Universal стал частью Angular, но все равно до сих пор, поставляется отдельно.

И если сказать, что реализация SSR в Angular имеет определенные сложности, то это значит не сказать ничего. Проще отстрелить себе ногу, чем реализовать правильный, быстрый Server Side Rendering.

По природе своей Angular представляет собой браузерную версию, где есть window, но нет global, и соответственно нет NodeJS.

И все было бы ничего, если бы не было Prerender’а - механизма предподготовленных страниц, которые можно скомпилировать заранее и не рендерить каждый раз при запросе клиента.

Серверная платформа Angular накладывает слишком много “НО” на разработку. 

  • Если используется что-то из Window, необходимо использовать isPlatformBrowser;

  • Если есть асинхронные гуарды (can-actives), то нужно писать правила для того, чтобы серверный рендер не уходил в бесконечное ожидание;

  • Если есть таймеры и интервалы как нативные, так и из rxjs, то их необходимо либо игнорировать в серверной платформе, либо переопределять наблюдателей;

  • Если используется пререндер, и у станицы есть асинхронный гуард, то он должен отдавать true, иначе пререндер уйдет в бесконечное ожидание;

  • Если для неизвестных страниц нужно отдавать страницу со статус кодом 404, на уровне всего приложения, то тогда на уровне ноды необходимо иметь sitemap или карту роутов, чтобы сервер по url мог понять, есть ли такая страница или нет;

  • Для всех Http запросов нужно решить - должны ли они выполняться при серверной сборке или нет. И тут много подводных камней. Если используется JWT в качестве сессии, то проблем будет чуть меньше. Однако, если в качестве авторизации используются куки, добро пожаловать в Ад. Будет необходимо выполнять запросы c withCredentials, но из-за того, что server это не browser то нужно будет пробрасывать все куки, что добавляет проблемы с безопасностью. Единственным верным решением будет нанять DevOps чернокнижника, который не проклянет вас и сможет все это разрулить. Иначе вы можете начинать учить латынь, а там уже доки по docker, kubernates, helm-chat’ам, ansible и многим другим интересным словам. Ах, да, еще есть ssl сертификаты.

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

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

И этот процесс бесконечный. Это становится первым кольцом обременения на шее разработчика.

Подытожить можно тем, что используя любую технологию нужно задумываться о её реализации в SSR, иначе красные не пропустят билд.

Redux в Angular

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

Ребята из Facebook начали генерировать множество потрясающий идей и библиотек. Так как собственные потребности в интерактивности росли, то facebook ничего не оставалось как придумать Redux - систему управления состояниями. Конечно, React дал разработчику redux из коробки, реализовав его в ядре библиотеки.

Angular же пошел другим путем, где сославшись на RxJS и DI отказался от какой либо имплементации Redux. И тогда на сцену вышел NgRx со своей системой reducer’ов, selector’ов и action’ов. Разработчики NgRx четко понимали, зачем нужен Redux и добавили мегафичу в лице Effect’ов - механизма выполнения асинхронных экшенов. 

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

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

- Почему это стало кольцом?
- Шариковое тестирование (marble testing).

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

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

Я наверное пропущу блок про тестирование в Angular, так как сейчас все используют jest, а Angular Team все еще не хочет перейти с karma на jest.

Монорепозиторий в Angular

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

Отпочковавшиеся от Angular Team разработчики объединили свои усилия и создали компанию Nrwl, которая начала консультировать компании из Fortune 500 на тему создания enterprise приложений. 

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

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

Основная проблема разработки в лице Dependency Hell была решена, что позволило взглянуть на разработку с нового ракурса.

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

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

- Решил сделать коммит?
- Сделай линт всех изменений.

- Решил запушить изменения?
- Запусти тесты на все изменения в файлах, а также на все связанные компоненты системы, которые используют измененные файлы.

Маркетинг и аналитика

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

Конечно, можно писать качественный, покрытый тестами код, но к сожалению, позволить это могут далеко не все. Для проверки разных гипотез, нужно временами менять до 10% кодовой базы, которая разрабатывалась несколько лет. И конечно, нет ни одного аргумента делать проверку гипотезы по всем принятым канонам. 

И тут есть одна ловушка, которая подкашивает большинство начинающих разработчиков:

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

И диалог будет следующий:

- Ну все же работает! Зачем что-то менять, пусть все остается так!

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

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

Влияние мобильных устройств на разработку

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

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

Потом появляется своя аналитика, так как обычная аналитика web версии уже не удовлетворяет потребностям отдела маркетинга, так как невозможно оценить стоимость рекламных кампаний в Google Play и App Store

Приложение обрастает новыми фичами и приходит момент, когда уже веб платформы становится недостаточно. 

И тогда в Angular приходит Ionic и NativeScript, которые обещают разработчику использовать текущую кодовую базу, добавив всего лишь компоненты обертки и немного изменив роутинг.

Quod licet Iovi (Jovi), non licet bovi.

Можно догадаться, что здесь открываются вторые врата в Ад.

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

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

Я собирал приложения в связке Nx + NgRx + Universal + Apollo + NativeScript, и к моему удивлению оно отлично работало. Конечно, всегда есть боль с обновлением Angular, когда выходит новая версия, но обычно за 2-3 месяца, выходит достаточное количество фиксов, что позволяет перейти на новую версию.

Магия найма

Последним кольцом является найм Angular разработчиков. Именно успех HR помогает сохранить жизнь и рассудок других Angular разработчиков в компании.

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

Это вызвано двумя ключевыми факторами: 

- Порог вхождения в фреймворк,
- Корпоративное рабство.

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

Мидл и миледи просят 350к, а сеньор и сеньорита просят от 500к.

Под корпоративным рабством подразумевается то, что компания в которой есть толковый разработчик, готова пойти на любые меры, чтобы удержать разработчика. В ход идут бонусы, 13 зарплата, фитнес, ДМС, зарубежные корпоративы, подписки на netflix и другое. 

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

Забавно, но один из российских IT гигантов заранее знал об этом. Это Yandex. Не для кого не секрет, что Yandex находится на темной (ну ладно, светлой) стороне силы, взяв в качестве инструментария React.

Совпадение? Не думаю.

А вот ребята Олега прогадали. Ну не совсем, конечно, но бизнес и часть сервисов точно задело.

Стоит отдать уважение ребятам из Tinkoff, за taiga-ui, что смогли выложить свои наработки в github. Работа там проделана громадная, но тоже временами видны некоторые проблемы с миграциями. Не знаю, получилось ли у них съехать с LESS на SASS  и навести порядок с рядом компонентов.

Хотя, даже если смотреть исходники Angular Material, то некоторые моменты вызывают слезы и тоску.

Enterprise кабала

Если обобщить вышесказанное, то получается следующая картина:

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

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

  • Если проект нуждается в SSR, то разработчик будет вынужден соблюдать большое количество правил и ограничений, который просто не позволят сбилдить проект.

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

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

  • Из-за сложности привлечения новых кадров, компании готовы пойти на любые меры, чтобы удержать сотрудников, что приводит к неоправданным затратам. А из-за малого предложения, каждый Angular разработчик будет работать за 3-4 человек. 

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

Решение только за вами. 

Заключение

В заключении хочется сказать только одно - Бегите глупцы. Flutter или Svetle уже вас ждут. 

P.S. Совсем забыл про NodeJS и Angular для backend’а - NestJS, где можно подключить TypeOrm, Redis, Rabbitmq, MongoDB, Graylog, Elasticsearch и Clickhouse. Но это немного выходит за рамки JavaScript. Ладно, пойду перепишу все на новый JS framework.

Комментарии (96)


  1. shai_hulud
    27.11.2021 12:31
    +23

    NgRx не является обязательным компонентом, он несет больше неудобства, чем пользы.

    А описание Angular в разделе "Enterprise кабала", выглядит как сплошные плюсы, для меня, как разработчика, кроме отдельной разработки для мобильных устройст.


    1. fafnur Автор
      28.11.2021 08:58

      Любое redux решение несет свои плюсы и минусы. И надо понимать, что Redux не панацея, но который позволяет решать некоторые насущные проблемы.


  1. tommy_lee
    27.11.2021 12:34
    +2

    Мидл и миледи просят 350к, а сеньор и сеньорита просят от 500к

    Зато

    переложить тестирование непосредственно на разработчика

    на тестировщике 100к сэкономили ????

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

    Зачем тогда вообще нужен фреймворк, который мешает зарабатывать деньги


    1. fafnur Автор
      28.11.2021 09:01
      -3

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


  1. Alexufo
    27.11.2021 13:02
    +11

    Без бутылки Карловского не разобраться.

    @nin-jin


    1. nin-jin
      27.11.2021 15:18
      +22

      Ща всё объясню..

      AngularJS был действительно сверхпопулярным фреймворком в своё время, но Angular-у даже похожего названия не хватило, чтобы набрать сопоставимую популярность. Причина тут в общей переусложнённости и необходимости полностью переписывать весь код. А раз уж всё равно переписывать, то есть куда более простые и быстрые альтернативы. Так что многие перешли на Vue (современная инкарнация AngularJS) или, на волне хайпа, на React. И даже те, кто по начало верили в Ангуляр и переписали код, потом всё-равно меняли коней. Я сам лично наблюдал за подобными процессами в Энтерпрайзе. Типичные причины:

      • скорость работы приложения

      • скорость разработки

      • сложность миграции между версиями

      Идея сделать фронт похожим на бэк витала у гугла довольно давно. И уже не раз проваливалась. Взять тот же GWT позволявший даже код писать на Java.

      RxJS - это отвратительное решение. Как архитектурно, так и в реализации. Они несколько раз меняли API до неузнаваемости, в итоге по сети разбросаны куча версий документации и неработающих примеров кода. А Stack Overflow просто забит вопросами в духе "хочу сделать простейшую вещь, но не пойму как это сделать на Rx".

      Redux - это просто рак. Но NgRx - это, пожалуй, лучшая версия редакса, ибо в нём хотя бы мемоизация селекторов есть из коробки. Но это всё-равно отвратительное архитектурное решение, мешающее переиспользованию компонент. Я лично под давлением переписывал приложение с MobX на NgRx, так что мне есть с чем сравнить: перфоманс просел в несколько раз, а объём кода, наоборот, в несколько раз увеличился. И ладно бы только объём, увеличилась и его сложность. Хотя, стоит признать, что по сравнению с голым RxJS, NgRx действительно упрощает код, ибо не надо постоянно решать головоломки.

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

      Компонентные тесты тоже дико тормозят, ибо каждый раз инициализируют пол мира. В итоге типичная оптимизация:

      • Выпиливаем Default стратегию детекта изменений.

      • Выпиливаем зоны.

      • Выпиливаем инициализацию пол мира для каждого теста.

      • В конструкторах инъектим только инъектор, а все зависимости уже лениво получаем через него.

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

      Когда мы начинали разработку $mol, мы смотрели и на Ionic, и на Polymer и на другие технологии гугла - всё это безбожно тормозило на мобилках.

      А так называемые Ангуляр-разработчики от 350к, которые умеют делать лишь квадратно-гнездовые приложения, - это прекрасный способ выбрасывать деньги на ветер. Показываешь им простой код на MobX, объясняешь как всё работает, - говорят, что не понимают, дайте нам NgRx, будем писать тривиальные селекторы в духе `a.b.c.d`, а к ним ещё и тестов забабахаем. И плевать, что они с редьюсерами разъедутся уже через неделю.

      Резюмируя: Ангуляр вообще ни разу не про энтерпрайз требования. Наоборот, только в энтерпрайзе может быть столько бардака (как в головах, так и в коде), что поделки типа Ангуляра не выбрасываются сразу, а продолжают хорошо кормить специфическую касту разработчиков, которые годами пилят тривиальные приложения, выдавая на выходе посредственный во всех смыслах результат.


      1. amakhrov
        28.11.2021 04:21
        +4

        DI в Ангуляре сделан через задницу. Никто не понимает как он работает.

        Как работает под капотом? Если очень интересно, можно поковыряться в коде фреймворка - но на практике это не нужно. Или непонятно, как пользоваться? И да, и нет. Да - много сложности, связанной с с наследованием инжекторов, параллельными иерархиями (view parent injector vs content parent injector). Но в большинстве случаев про это и не думаешь. Для типового использования там все понятно, и есть приличная документация.

        Работает он медленно.

        А можно подробнее? Какие именно кейзы медленые? Медленные по сравнению с чем?

        А поддержка кода с ним крайне переусложнена

        Субъективно.


        1. Alexufo
          28.11.2021 04:53

          Да — много сложности, связанной с с наследованием инжекторов, параллельными иерархиями (view parent injector vs content parent injector). Но в большинстве случаев про это и не думаешь

          Это запах технологической сингулярности.

          «если усложнение техники часто совершенно не оправдано, то почему же она все-таки непрерывно усложняется, причем все возрастающими темпами?»

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

          Сложность технологии должна быть оправдана, а не сложность должна оправдывать технологию.


        1. nin-jin
          28.11.2021 10:19
          +3

          I've read about Angular Dependency Injection, but I'm very confused with a very simple example with lazy loaded module.

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

          Добавил в класс зависимость - изволь добавить её же в конструкторы всех потомков до последнего колена и во все их юнит-тесты. Удалил зависимость - то же самое. Хочешь перейти к коду зависимости из места её использования - успехов в поиске. Зависимости регистрируются через токены, по которым можно положить всё, что угодно. И конечно же по каждому чиху надо создавать дополнительные модули, чтобы это всё просто работало.


          1. mayorovp
            28.11.2021 10:28
            +1

            Но основные тормоза в том, что при создании объекта создаются все его зависимости, зависимости зависимостей и так далее. Даже если в конкретном кейсе объект вообще к зависимостям не обращается.

            Это ж где вы столько зависимостей, к тому же не являющихся синглтонами, нашли...


            Добавил в класс зависимость — изволь добавить её же в конструкторы всех потомков до последнего колена и во все их юнит-тесты. Удалил зависимость — то же самое.

            И это тоже разрешимая проблема, было бы желание. Кстати, что там про наследование и композицию говорится?


          1. amakhrov
            28.11.2021 10:55
            +2

            Но основные тормоза в том, что при создании объекта создаются все его зависимости, зависимости зависимостей и так далее.

            Так Ангуляр тут не причем. Это в принципе вся суть и соль DI. И вдогонку - большинство зависимой - синглтоны, они создаются один раз и потом переиспользуются.

            Даже если в конкретном кейсе объект вообще к зависимостям не обращается.

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

            изволь добавить её же в конструкторы всех потомков

            Composition over inheritance наше все. Ну то есть, конечно, кейзы бывают разные. Но если это начинает вызывать боль - возможно, где-то вы черезчур ударились в наследование. И снова это не проблема, специфичная именно для Ангуляра.

            Хочешь перейти к коду зависимости из места её использования - успехов в поиске

            Этого я вообще не понял. Если вы внедряете конкретный класс, то в чем проблема вообще? Если абстрактный / токен - то да, конкретная реализация может быть разной, придется поискать. Но ведь в этом и смысл - сделать разные реализации для разных сценариев.

            Зависимости регистрируются через токены

            Примерно в 1% случаев. Подавляющее большинство случаев - внедрение конкретного класса. Вручную ничего никуда не кладешь.

            И конечно же по каждому чиху надо создавать дополнительные модули

            Конечно же, нет. `providedIn: "root"`. Модули в приложении все еще нужны - но по другим причинам (основная - для описания компонентов, чтобы ангуляр знал, как маппить html-разметку в шаблоне на директивы; и команда работает над тем, чтобы сделать модули в этом кейзе опциональными)


            1. nin-jin
              28.11.2021 11:15

              В тестах не переиспользуются. Да и делать все сервисы синглтонами - такое себе.

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

              Композиция не решает проблему с зависимостями, а наоборот усугубляет.

              Внедрение конкретного класса ничем не лучше отсутствия DI вообще.


              1. amakhrov
                28.11.2021 22:49
                +1

                А, я не понял, что мы про тормоза DI в тестах, а не в приложении.

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

                В общем, звучит так, будто вы против DI как такового, а не против конкретной реализации его в Ангуляре. Ок, имеете право. Более того, даже в Ангуляре вы вполне можете им не пользоваться, а все зависимости брать через инжектор (а-ля Service Locator) или просто глобальные переменные. Ради бога.

                Просто утверждение "DI в Ангуляре тормозной и через задницу" остается голословным.


                1. Alexandroppolus
                  28.11.2021 23:03

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

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


                  1. MisterN
                    28.11.2021 23:15

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


                    1. Alexandroppolus
                      28.11.2021 23:49

                      Типа, вот поменяли класс (а точнее интерфейс), от которого зависят несколько других, то и заглушку, которая этот класс изображает, тоже везде надо менять? Да, есть такое дело. Если все тесты написаны на TS, то сразу высветится, где старая заглушка, не соответствующая новому интерфейсу. Я правильно понял ваш поинт?


                      1. MisterN
                        29.11.2021 08:23

                        Это если типизация возвращаемого изменится, то да, тайпскрипт не собирётся. А если логика возвращения? В моке допустим возвращается массив из двух объектов, а реально метод даёт другой, хоть и соответствующий интерфейсу. Если бы типизация позволяла исключить такие проблемы, то и тесты были бы не нужны


                      1. Alexandroppolus
                        29.11.2021 09:10
                        +2

                        Если тестируемый класс получает на вход массив из объектов, то предполагается, что в этом массиве может быть ноль или несколько итемов, и все кейсы надо правильно обработать и покрыть тестами. А если там закладывались на два элемента, причем у нулевого и первого есть некоторый свой "смысл", то правильнее передавать не массив, а объект с двумя полями, названными соответственно. Либо, на крайний случай, тип указать не массив, а кортеж.


                      1. MisterN
                        29.11.2021 20:48
                        +3

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


                      1. Alexandroppolus
                        30.11.2021 12:05
                        +2

                        Тем более, что на тестах эта зависимость мокается и до сих пор складывает два числа.

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

                        При это зависимость (A) и зависимое (B), если рассматривать их отдельно, вполне могут быть правильными, а вот их связка - неправильной. Но тогда должны упасть тесты того "верхнего" кода, который эту связку делает (по принципу DIP, реализации A и B исходно не знают друг про друга и соединяются отдельно).


                      1. MisterN
                        01.12.2021 13:53
                        -1

                        Если класс непосредственно инжектит в себя какую-то зависимость и пользует её в своих методах, то какой тут должен быть "верхний код"? "правильная-не правильная" понятия изменяемые с течением времени и в предложенном примере одна зависимость все-таки отстала от другой и стала "неправильной".

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

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

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


                1. nin-jin
                  28.11.2021 23:23

                  В приложении тоже все зависимости часто сразу не нужны.

                  О том, как правильно писать тесты у меня есть отдельная статья: Фрактальное тестирование

                  Я просто не стал грузить новыми терминами. IoC в Ангуляре через задницу (DI). А вот инжектор - это уже передница. Но это не Service Locator, ибо не синглтон.


          1. flancer
            28.11.2021 20:24

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

            Вот для этого и нужны пространства имён (package, namespace). А от них уже и цивилизованный DI вытанцовывается.


            1. nin-jin
              28.11.2021 21:00
              +1

              А какая связь пространств имён с DI?


              1. flancer
                28.11.2021 22:01
                +1

                Ну, как бы нужно знать, откуда что взять, чтобы что-то куда-то вставить. А когда всякого много, нужно понимать, где находится то, что "откуда". В общем, каждый элемент кода, который может быть зависимостью, должен иметь свой уникальный адрес в пределах всей кодовой базы приложения. А это и есть задача namespace'ов - иерархическая адресация. Просто DI можно и без подобной адресации сделать, а цивилизованный - уже нет.


                1. nin-jin
                  28.11.2021 23:28
                  +1

                  А, вы про конфликты имён. Да, в идеале имена должны быть глобально уникальными, а не только в рамках приложения, тогда можно легко шарить код между приложениями и даже компаниями. В $mol так сделано.


                  1. flancer
                    29.11.2021 00:03

                    Я про адресацию элементов кода. Но раз вы в своей статье по ссылке упомянули про PSR-4 и автоматическую загрузку исходников, то и вы в курсе связи пространств имён с DI.


          1. Zy2ba
            29.11.2021 11:44

            Для справки - если делаете наследование, то можно инжектить не через аргументы конструктора, а с помощью функции inject (именно с маленькой i). Например прямо в поле класса как его начальное значение. Пример можно увидеть вот в этой статье:

            Возможности Angular DI, о которых почти ничего не сказано в документации / Хабр (habr.com)


        1. essome
          01.12.2021 22:46

          Я сам лично наблюдал за подобными процессами в Энтерпрайзе. Типичные причины:

          • скорость работы приложения

          • скорость разработки

          • сложность миграции между версиями

          Миграция очень медленная и сложная, ведь там нужно:
          1. Запустить ng update


          1. nin-jin
            01.12.2021 22:56

            Все сторонние компоненты оно тоже обновит, да? Тайпскрипт тоже свежий подтянет? И поправит все несовместимости в типах при обновлении тайпскрипта?


            1. essome
              02.12.2021 00:18

              Да, все подтянет, там где несовместимости укажет об этом и предложит исправление.


              1. nin-jin
                02.12.2021 01:16

                О, ну я знаю, как ТС предлагает исправления: вываливает 100500 тайп-трейсов и сиди разбирайся, почему типы не сошлись.


              1. JustDont
                02.12.2021 12:02

                Вы к нам из далекого альтернативного будущего?
                Потому что в моей реальности TS просто предлагает тебе переписать проект, пока транспилятор не скажет, что с типами всё ок. В зависимости от объема начального кода — это легко может выливаться в работу месяцами, даже несмотря на то, что рефакторинг тут часто несложный (но не всегда, удачи разбираться с нестрогой типизацией, которая в определенных старых версиях TS "прокатывала", а в новых уже не будет).


                1. essome
                  02.12.2021 12:35

                  2 года назад получил проект с кучей легаси и даже jquery внутри angular, обновлял его с 8 до 12 версии постепенно, на каждое обновление не уходило больше 1 рабочего дня.

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

                  Так же обновления ts не относятся конкретно к angular, это нужно делать на любом TS проекте.


                  1. JustDont
                    02.12.2021 12:40

                    Ну давайте предметно: сколько было LoC?


                    Так же обновления ts не относятся конкретно к angular, это нужно делать на любом TS проекте.

                    Обновлять TS "на любом TS проекте" можно через обновления TS. Обновлять TS на ангуляре необходимо исключительно через обновления ангуляра.


                    Проект был без строгого режима

                    Ну понятно. То есть нормальной типизации не было, и не стало после обновления. Тут действительно всё отлично. Подозреваю, что если в проекте везде типы any — то вообще никогда никаких проблем с обновлением TS не будет. Профит!


                    1. essome
                      04.12.2021 13:50
                      -1

                      Ну понятно. То есть нормальной типизации не было, и не стало после обновления. Тут действительно всё отлично. Подозреваю, что если в проекте везде типы any — то вообще никогда никаких проблем с обновлением TS не будет. Профит!

                      Судя по ответу как раз не понятно.


      1. fafnur Автор
        28.11.2021 09:07
        +1

        В целом да, все по существу. Только если из Angular убрать DI, Zone, то это уже не ангуляр будет.

        Если нужна производительность, то конечно, нужно использовать нативные средства и redux в этом случае - противопоказан. Но так в любом highload, неважно back это или фронт.


        1. nin-jin
          28.11.2021 10:28

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

          До highload мы ещё и не дошли, все эти проблемы проявляются уже на lowload-е. А если нужна производительность - нужно использовать нормально спроектированную архитектуру, а не велосипедить в узких местах на нативе.


  1. dimuska139
    27.11.2021 13:36
    +6

    Миграция с PHP на TypeScript стала обыденностью.

    В статье, вроде, речь про фронтенд идет, при чем тут php? Фронтенд был на php?


    1. hello_my_name_is_dany
      28.11.2021 08:15
      +3

      PHP всё же был шаблонизатором изначально, это потом уже вырос в нечто большее


    1. anudas
      28.11.2021 09:08

      Здесь речь про монолит, наверное. Можно разделить приложение на фронт и бэк, где в обоих местах тайпскрипт


    1. fafnur Автор
      28.11.2021 09:10
      -3

      Это шутка чисто потроллить моих коллег. Не принимайте близко к сердцу :)


  1. apapacy
    27.11.2021 13:57
    -6

    Много букофф. Слишклм много букофф. Пока Вы печатали этот текст vuejs догнал в трендах гугла реакт. А в перспективе обгонит в пару раз. И тут важно то что в отличие от angular реакта, vuejs легок в освоении и им может воспользоваться верстала. Фактически профессия фронтенд разработчика где знание и отыт верстки и фреймворка совещены в одном человеке только теперь начинает складываться. До этого были такие себе фулстек-интеграторы, переучившиеся с php (вот кстати откуда в тексте php) на js, немного шараящие в css (а что там учить!). Такому интегратору нужено с каждого бока по помощнику (там подверстать, там с логикой помочь). Изучать верстку ему скучно. И это недоразумение уже сейчас становится прошлым.


    Кстати, специально для господ минусующих. Ваш минус не остановит технический прогресс в угоду вашим проблемам.


    1. tommy_lee
      27.11.2021 14:34
      -1

      А разве верстку не делает Figma уже автоматически?


      1. apapacy
        27.11.2021 15:49
        +5

        Ровно настолько насколько тильда делает сайты автоматически


    1. Bigata
      27.11.2021 15:20
      -2

      Сам не пойму, почему заминосовал. Vue не любят????


      1. dev-eugen
        29.11.2021 07:10

        Я женился на vue


        1. Alexufo
          29.11.2021 14:37
          +1

          дети есть?


  1. themen2
    27.11.2021 15:27
    +5

    Всегда было ощущение, что веб - это про гипертекстовые документы. Натянуть desktop ui на веб - врятли получится что-то удобное в плане скорости разработки и конечного результата.

    "Старый веб" - это документы, генерируемые сервером, все описывается в стандартах , стандарты не так часто меняются. В целом понятно как с этим работать.

    А в современном пытаются реализовать на технологиях , не очень для этого приспособленных, полноценные ui приложения. До ещё и часто смешать это с серверным рендерингом, чтобы работало SEO.

    Хочется приложение? Тогда надо и делать приложение! И по идее, кажется что нишу приложений в вебе должны занять инструменты по типу Flatter, а веб должен остаться для документов, для этого он и создавался.

    Если что , это все мое личное мнение.

    Ещё момент - завязка на проприетарные технологии несёт в себе риски для разраба как мне кажется. Мало ли через некоторое время Фейсбук или Гугл откажутся от реакта , ангуляра итд, появится какой то новый подход. И что будут делать такие разрабы - как им конкурировать с новыми разработчиками?! По идее эту проблему должны решать стандарты (хорошо продуманные), которые создают независимые комитеты, чтобы Гугл и Фейсбук или др не форсили свои хотелки


    1. atomic1989
      27.11.2021 16:30
      +7

      Вся фишка в том, что только веб позволяет одним кодом работать на разных ОС, платформах и т.д. Нанимать команду под всякое разное будет дороже, чем веб со всеми своими сложностями и хромыми лошадьми. На выходе результат, который удовлетворит на 80%. Да и веб ускакал от былых времен далеко


      1. themen2
        27.11.2021 22:12

        Если мы говорим о приложениях , а не о документах, то чтобы рисовать ui, нужен только canvas от браузера. Это и делает флаттер - он все зановоно рисует на канвасе. То есть команда хрома (они его делают) смогла за несколько лет сделать годный движок для написания кроссплатформенных приложений в том числе и для веба.

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

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

        Но где то это уже было - flash, silverlights, java applets :)

        Посмотрим, может у флаттера получится)


        1. Chamie
          28.11.2021 04:52
          +4

          Как в вашем канвасе в аксессибилити, если не секрет?


      1. Alexufo
        29.11.2021 14:38

        А джава? Хотя причем тут джава… веб покрывает сильнее


    1. Alexandroppolus
      27.11.2021 17:20
      +8

      Разговоры про "веб - это сотворенные на серваке документы" ведутся уже лет лет 16, с тех пор как Дж.Дж. Гаррет "изобрел" аякс (а по факту даже раньше были крутые решения, например гуглпочта и карты). Думается мне, эта тема слегка устарела.


  1. Sm1le291
    27.11.2021 16:03
    +3

    Если пару лет назад шли вопросы о том, какой фреймворк выбрать, то сейчас все задаются вопросом: “Как оттуда выбраться”.  Давайте разберемся с тем как это произошло, и что стоит делать, чтобы не попасть в жернова фронтенд фреймворка.

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


    1. fafnur Автор
      28.11.2021 09:20
      +3

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

      И фреймворк тут не важен:
      - с Angular на React,
      - с React на Vue,
      - с php на Java
      - c Java на C#

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


  1. c_kotik
    27.11.2021 17:18
    +6

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


    1. fafnur Автор
      28.11.2021 09:20
      -2

      Всегда рад стараться! :)


  1. atomic1989
    27.11.2021 17:30
    +10

    Статья как по мне не совсем доработана и однобока. Типа фразочки если использовать что-то из Window, то ..... Это разве ограничение angular? Нет, это особенности запуска и работы среды node.js. Да и эмуляторы есть. Многие другие пункты из SSR дали понять о не высоком уровне автора. Кстати flutter для веба в результате тот же js, css, html. Быстрее не будет. Что flutter и svelte хороши в своих областях, но и они не универсальны. Предположу, что автор больше занимается мобильной разработкой или приложений с несложной логикой. Как для примера большинство продуктов yandex. Поэтому и очевиден выбор в пользу react. Сам бы голосовал "за" в их положении.

    Для меня angular отличное решение для крупных корпоративных решений(для которых чаще SEO и SSR не нужны). Он совмещает в себе функционал и гибкость(что сейчас редкость). Разработка крупных проектов требует совершенно иной подход. DI реализован настолько хорошо, насколько позволяет ts. Да, может не самый быстрый(как пишут в комментарии выше), но он позволяет упростить сложные взаимодействия сервисов, разделению кода, подмену реализации(возможность переиспользовать компоненты в разных контекстах). В связке с mobx(куда самостоятельно прикрутили DI) упростил работу с проектом. redux или его производные как ngrx, для angular проектов не рекомендую. Не помню спикера, но с ним согласен: redux хорош там, где в основном собраны младшие разработчики. Правила игры, который предлагает angular позволяют понимать хорошо участников команды друг с другом, включая новичков. Для примера общаясь с ребятами из аутсорс, которые занимаются разработкой на react говорили по сути одно и тоже. Каждый проект заказчика просто уникален своим подходом, зоопарком и динозаврами. Порой отличаются очень сильно. React без поддержки контекста и хуков и современный react требуют разный архитектурный подход. В общем процесс перехода из одного проекта на другой сложен.

    Каждая библиотека или фреймворк хороша в рамках своей области применения. Не надо на angular писать типичный веб сайт.


    1. themen2
      27.11.2021 22:20
      +1

      Из документации flatter

      HTML rendererUses a combination of HTML elements, CSS, Canvas elements, and SVG elements. This renderer has a smaller download size.

      CanvasKit rendererThis renderer is fully consistent with Flutter mobile and desktop, has faster performance with higher widget density, but adds about 2MB in download size.

      То есть насколько я понял есть два варианта и один из них - просто канвас от браузера и все. Дальше он рисует все сам. Так что может быть и быстрее


      1. atomic1989
        27.11.2021 22:47
        +1

        Спасибо за информацию,боюсь через canvas не каждому подойдет


    1. fafnur Автор
      28.11.2021 09:27
      +1

      Я не говорил, что Angular плох и что его не стоит использовать. Angular отличное решение, как и React, Vue или Svetle. Вообще все огонь :) Жалко что времени нет, все переписать.

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


  1. Bromka
    27.11.2021 17:48

    Flutter вообще никакая не альтернатива, как минимум потому что он очень похож на Angular


    1. Alexufo
      27.11.2021 18:39
      +1

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


    1. fafnur Автор
      28.11.2021 09:29

      Стоит попробовать переписать все с Angular на Flutter :)


      1. Xuxicheta
        28.11.2021 15:50

        А можете рассказать, что вы сами переписали на Flutter и какие преимущества это дало? Это была бы статья гораздо более интересная, чем эта.


  1. strannik_k
    27.11.2021 20:13
    +9

    Ребята из Facebook начали генерировать множество потрясающий идей и библиотек. Так как собственные потребности в интерактивности росли, то facebook ничего не оставалось как придумать Redux - систему управления состояниями. Конечно, React дал разработчику redux из коробки, реализовав его в ядре библиотеки.

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


    1. fafnur Автор
      28.11.2021 09:32
      -5

      Хорошую историю грех не приукрасить. Слукавил, признаю.


  1. DarthVictor
    27.11.2021 22:01
    +3

    то facebook ничего не оставалось как придумать Redux - систему управления состояниями.

    Вообще в Facebook был придуман Flux. И придуман он был в 2014 году, то года за два до второго Angular. Что Redux, что MobX были придуманы за пределами Facebook.

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

    - Решил сделать коммит?
    - Сделай линт всех изменений.

    - Решил запушить изменения?
    - Запусти тесты на все изменения в файлах, а также на все связанные компоненты системы, которые используют измененные файлы.

    Я надеюсь, что автор троллит, и на саммом деле автор не думает, что автотесты и git-хуки придумали в Angular.

    Я собирал приложения в связке Nx + NgRx + Universal + Apollo + NativeScript, и к моему удивлению оно отлично работало. Конечно, всегда есть боль с обновлением Angular, когда выходит новая версия, но обычно за 2-3 месяца, выходит достаточное количество фиксов, что позволяет перейти на новую версию.

    Ну то есть все так же как и в React, только есть боль с обновлением.


    1. bromzh
      27.11.2021 22:35
      +3

      только есть боль с обновлением

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


  1. pavelsc
    27.11.2021 23:27
    +2

    Совсем забыл про NodeJS и Angular для backend’а - NestJS, где можно подключить TypeOrm, Redis, Rabbitmq, MongoDB, Graylog, Elasticsearch и Clickhouse.

    А что ангулярщики без nestjs все эти redisio, amqp и mongoose не смогут в nodejs подключить? Не понял этот подчеркивание "невероятных" возможностей


    1. fafnur Автор
      28.11.2021 09:36

      Это шутка про компот технологий. Когда спрашиваешь - На чем у вас все крутиться, - и там понеслось.


  1. tbl
    27.11.2021 23:56
    -4

    Единственная ниша для ангуляра - писать админки к внутренним сервисам. Там в принципе даже не нужен фронтенд-разработчик и всякие головняки с SEO и переписыванием в угоду проверки гипотез маркетинга. Для формошлепства идеально, даже валидаторы есть, если стандартных не хватает, то можно свои накодить. И в этом случае на ангуляре достаточно быстро начинают писать java-бэкендеры, многие концепции им понятны: и строгая типизация в typescript, и DI, и реактивщина. Но и то, в этой нише с ним конкурирует react (благодаря его поддержке со стороны kotlin), или вообще статические html-страницы с шаблонизатором типа thymeleaf


  1. amakhrov
    28.11.2021 04:20

    дубликат (промахнулся веткой)


  1. OhSirius
    28.11.2021 09:37

    Хорошая статья. Мне кажется здесь проблема не только в angular, сложность системы диктуется бизнесом. До react/angular фронты пилили не поддерживаемые костыли.

    Здесь 2 подхода как на бэке - пишем на фреймворке (spring java), либо на библиотеках для опытных (ФП scala).


  1. spaiki007
    28.11.2021 09:37
    +1

    Сейчас где то vue курит в сторонке, и говорит, сраный биомусор вы все


  1. gnome2_terminal_is_best
    28.11.2021 09:37

    Вот этот момент:

    Если для неизвестных страниц нужно отдавать страницу со статус кодом 404, на уровне всего приложения, то тогда на уровне ноды необходимо иметь sitemap или карту роутов, чтобы сервер по url понять, есть ли такая страница или нет;

    вообще не понятен.


    1. fafnur Автор
      28.11.2021 09:44

      Это про индексацию. Если есть много неверных ссылок на сайт (/bla-bla-bla), то google будет понижать в выдаче. Ну раньше мне так казалось, сейчас трудно сказать.

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


  1. metalidea
    28.11.2021 09:37

    Когда кодил на Angular и Vue (два параллельных проэкта), я мягко говоря недолюбливал React, за его сложность, что там нет строгих правил и некоторые вещи приходится придумывать заново. Перешёл на React и теперь не хочу обратно на Angular из за его сложности)) а во Vue теперь вобще кажется какая то магия, пахнущая AngularJS. Но к слову сказать некоторые вещи я перенес из Angular в React, просто потому что они там хорошо реализованы (типа guards на роутах).

    Тут от разработчика и архитектуры многое зависит. На Angular можно писать быстрые и понятные энтерпрайз приложения, без Rx лапши, если руки прямые.


    1. Xuxicheta
      28.11.2021 11:01

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


  1. Xuxicheta
    28.11.2021 11:34
    +5

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

    А остальное просто набор разрозренных фактов, который порой вообще к Angular не относятся, или относятся ко всему фронтенду в целом. Еще и редакс каким-то боком затесался. За последние 4 года разработки на Angular я редакс толком ни разу не использовал и ни разу не пожалел.

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

    По факту, это хороший фреймворк, со своими минусами, но я редко встречал людей, которые после Angular хотят перейти на что-то еще. Просто потому что не хочется менять комплексное отточенное решение на ворох странного.
    А реальные минусы Angular тут не рассмотрены вообще никак.


    1. nin-jin
      28.11.2021 11:53

      Самый большой реальный минус Ангуляра - это 3 года на "оттачивание" детской болезни в базовой функциональности, которой при нормальном проектировании вообще не должно быть заточено.


      1. Xuxicheta
        28.11.2021 12:20

        соглашусь, что к коду роутера, форм и особенно материала есть множество вопросов. Порой проектирование там весьма странное.

        Для некоторых своих случаев я писал собственный routerLinkActive 


  1. Mikluho
    28.11.2021 13:21
    +6

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

    Но начну чуть издалека. Во-первых, задолго до ангуляра и айфона появился asp.net web forms (2002 год, и да, C# - это си-шарп), вот там реально была разработка в вебе как в декстопе. К тому моменту мы в компании разработали сайт, который работал примерно на всём, от коммуникаторов до телевизоров, не считая компов. А на самих web forms я написал первое в своей работе SPA, примерно в 2005-м.
    Это я к тому, что многие описываемые тут проблемы пришли не после айфона и ангуляра, а раньше. И ни один инструмент/фрэймворк или что-то ещё не решает всех проблем, не является универсальным средством.

    Не корректно говорить, что инструмент плох только потому, что не подходит в конкретных обстоятельствах.

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

    У нас приложение для внутреннего пользования. Никогда не потребуется адаптация под мобильники (а даже если и да, что лишь крошечные фрагменты, т.к. большая часть функций в принципе невозможно использовать на мобильнике), нафиг не нужен SEO, нас даже не сильно волнует оптимизация размера бандла или то, сколько памяти съест запущенное приложение в браузере (в определённых пределах, конечно), т.к. эта оптимизация для компании дороже потенциальной выгоды, причём на много.
    Нам не нужны очень многие подходы в современной веб-разработке. И даже автотесты нам нужны на всё приложение, и запускаться они будут по пользовательским сценариям в режиме запуска браузера и выполнения там пользовательских действий.

    Ну и в довершение, мы в команде большую часть времени тратим на разработку UX для сложного workflow/dataflow и работы с данными (таблички - наше всё), и чем меньше сил отбирает разработка фронта, тем лучше. Ангуляр с этим в наших обстоятельствах справляется, на мой вкус, лучше других популярных решений.


  1. JustDont
    28.11.2021 15:32
    +2

    Статья почти кругом субъективщина. Но ангуляр можно пинать бесконечно, это правда.
    Вообще в ангуляре много хороших концепций, появившихся там тогда, когда обычно просто говнокодили без них. Беда в том, что реализация этих концепций там почти всегда плохая, т.к. остальной мир уже давно научился действовать лучше, а в ангуляре всё по-прежнему.


    1. DI. Реализация DI в ангуляре — это отличный пример того, как можно запредельно усложнить довольно простую вещь, и запредельно затруднить её отладку, если что-то идёт не так.
    2. Zone. В мире уже лет пять с лишним как научились экономно работать с обновлениями страницы в enterprise-grade библиотеках и фреймворках. Ангуляр всё так же живет в мире "или я перерисую всё сразу, или я… перерисую всё сразу, а ты мне будешь говорить, когда". Тут есть один плюс — это очень просто для понимания. Всё остальное — минусы, и минусы запредельные. Справедливости ради, подход ангуляра в целом нисколько не лучше подхода реакта, в первом случае есть выбор между "сделаю как умею" и "делай всё сам, если такой умный"; а во втором — выбора нет, реакт сильно умный и всё всегда будет делать сам, вот только не факт, что быстро. А разработчик обычно узнает об этом, когда на ровном месте начинают тормозить очень простые вещи.
    3. Rx. Ну тут nin-jin уже всё сказал, в т.ч. и в статье про реактивность. Но я бы еще добавил вишенку на торт — будучи официальной либой для реактивности в ангуляре, RxJS собственно интегрирован с ангуляром на крайне убогом уровне удобности. Кроме "| async" у вас по сути никакой прямой интеграции и нет, "| async" будет отставать от любого синхронного обновления UI на один ангуляровский цикл, а циклы обновления тут весьма небыстры и визуально очень заметны. Что, вам не нравятся лагающие UI? Ну тогда сидите и перекладывайте из обсерваблов в обычные переменные, а потом фигачьте (о, ирония) эти значения в ангулярские эвент эмиттеры, которые опять из мира Rx (потому что обертка на Subject).
    4. Шаблоны. Ангуляр тут немного спасает только то, что офигенных шаблонов нет ни у кого (просьба помолчать про $mol), и всегда есть проблемы с ограниченностью DSL шаблонов и необходимостью какого-то особого нескучного тулинга, чтоб вообще с ними продуктивно работать. Так что в ангуляре с шаблонами просто "плохо, но у других тоже в общем-то плохо".
    5. Залочка версии TS. За это отдельные лучи добра от всех, кто в типичном энтерпрайз-"работает, и не трогай"-мире вынужден сидеть со старыми версиями ангуляра, и при этом даже не может пользоваться нормальными типами, потому что актуальный TS уже давно уехал вперед, а TS на ангулярском проекте невозможно обновить отдельно от самого ангуляра.


  1. MisterN
    28.11.2021 17:49
    +1

    Под корпоративным рабством подразумевается то, что компания в которой есть толковый разработчик, готова пойти на любые меры, чтобы удержать разработчика. В ход идут бонусы, 13 зарплата, фитнес, ДМС, зарубежные корпоративы, подписки на netflix и другое. 

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

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

    ...

    Большое количество ограничений и стандартов вынуждают разработчика соблюдать множество правил

    Сложность-то во всяких энтерпрайзовых фичах типа DI и стандартах и том, что фреймворк заставляет понимать стандарты? Ну так оно в энтерпрайзе и надо, чтобы все маршировали в ногу, а не каждый по-своему. В FizzBuzz энтерпрайз-версия не нужна, а в каких-то приложениях необходима. Банальная мысль, причем здесь ангулар?

    Наверно нет смысла держать в курсе, что и мы не пользуем серверный рендеринг, и у нас нет толком юнит-тестов на фронте по большому счету, и у нас нет задачи оптимизировать производительность (в разумных пределах). А вот с мобильными устройствами засада.

    Мобильные устройства, которые все больше определяют современный рынок

    Есть у нас бекенд и фронтенд на ангуларе. Понятное дело, вся бизнес-логика на беке, вертится на удаве, фронт лишь дает кнопочки и формочки. И вот нас полностью устраивал шерринг кода от nativescript, позволяющий просто поменять расширение для мобильных шаблонов на .tns.html, и получить мобильную версию. фронт занимался своим делом - чисто стилизацией и кнопочками, нам не нужно выносить бизнес-логику в какую-то отдельную либу на javascript, возможность юзать специфические шаблоны для мобилки и этим отделаться стала просто подарком. Не все шло гладко, веб-гриды на мобильный шаблон толком (так чтобы было удобно) не удалось отобразить. Гриды все-таки веб-тема, а не мобильная. Где-то наоборот, получилось очень удачно и мы заюали апи андроида, добавив необходимый функционал, которого не было в веб-версии по причине ненужности, но который удачно встал в мобильной версии. Я бы сказал, что когда нужно чисто-мобильное приложение, то следует использовать нативные технологии, джаву. Но в целом положение вещей нас полностью устраивало и мы были довольны нативскриптом и тем, как он помогает сэкономить силы и поддерживать мобильную версию, которая не отстает от веб-версии ни в чем. Я на пол года или больше выпал из поддержки мобильной версии, а тут фигась - и нативскрипт отменили у себя шерринг кода и больше не поддерживают. Ангулар мы планово обновляем, нативскрипт тоже, это неизбежно. И че за дела, как так и че делать? Пока вопрос с мобильной версией не актуален, но в будущем похоже придется либо самим реализовать шерринг кода, либо нафиг писать нативную мобильную апликуху. Внезапно, вроде все хорошо было, ничего не предвещало...


  1. some_x
    29.11.2021 06:37
    +2

    Мидл и миледи просят 350к, а сеньор и сеньорита просят от 500к.

    Это либо ошибочное экстраполирование какой-то частности либо я как-то очень не правильно копаю рынок труда. Можно точнее где искать вакансии senior angular от 500к?


    1. MDie
      29.11.2021 08:10

      так просят, это не то же самое, что предлагают.


      1. MisterN
        29.11.2021 09:44

        От оно чего, а зачем тогда указывать цифры, которые просят, а не получают?


        1. MDie
          29.11.2021 09:52

          потому что могут, видимо :) а вдруг?


          1. MisterN
            29.11.2021 10:46
            +1

            Почему просят - понятно. Вопрос, почему авторы статей не у пускают случая несколько преукрасить текст, не явно выдавая желаемое за действительное?)))

            Эдак просящих будет только больше, но получат ли они желаемое? Нереализуемые желания развивают неврозы же))


            1. MDie
              29.11.2021 10:50

              не могу с Вами не согласиться :)


  1. Danik-ik
    03.12.2021 23:14

    Мидл и миледи просят 350к, а сеньор и сеньорита просят от 500к.

    После этой фразы смог думать только о том, как в подобном стиле назвать даму-джуна. И правда, как?


    1. MisterN
      04.12.2021 10:39

      С дамой мидлом уже как то криво вышло. Он же не милед. Куда там джунеорку обозначить?


      1. Chamie
        06.12.2021 15:01

        Юниор и юниорка не сойдут?


        1. MisterN
          06.12.2021 18:05

          Юниор - это что-то советско-спортивное.А тут джунки - джутянки