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

Здесь мы видим новый синтаксис призванный упростить запись
Здесь мы видим новый синтаксис призванный упростить запись

Angular теперь поддерживает специальные декораторы в HTML на замену *ngIf и прочих «устаревших» структурных директив.

Так выглядит "устаревший" метод записи
Так выглядит "устаревший" метод записи

Прирост читаемости конечно есть, но он весьма символический, действительно избавляемся от лишних слов ng-container и ng-template (но учить новичку их все равно придется), конструкция выглядит чуть короче, это плюс. По количеству строчек, однако, то же самое. Но лучше бы о таком думали в первых версиях, а не когда уже треть приложений в мире на Angular написана. Самое время подумать о новичках. А ведь новичок который придет на любой проект все равно увидит там *ngIf и прочие конструкции и их ему также придется выучить.

В реальной жизни конечно большинство напишет конструкцию ниже, потому что в 99 процентах случаев ухудшение производительности приложения будет неизмеримо, а код будет заметно короче

Пример того, как это зачастую пишут в реальных проектах в жизни
Пример того, как это зачастую пишут в реальных проектах в жизни

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

Как давно мы ждали такого счастья, правда?
Как давно мы ждали такого счастья, правда?


Приведу выдуманный пример который отражает суть моих мыслей.

Мы привыкли пользоваться некоторыми инструментами, например плоскогубцами и бокорезами.

А Angular нам такой говорит: «Наконец‑то свершилось! Вам больше не нужно пользоваться старыми и неудобными инструментами, потому что специально для вас сегодня мы представляем вам новые инструменты: плоскорезы и бокогубцы! Плоскорезы делают тоже самое что бокорезы но внешне и по названию похожи на привычные всем плоскогубцы! А бокогубцы делают тоже что и плоскогубцы, но теперь они наконец‑то выглядят единообразно с бокорезами! И отныне для того чтобы пользоваться инструментами, в том числе и старыми, нужно будет использовать перчатки, а все что ранее было сделано без них придется переделать и все это ради чистоты и техники безопасности на рабочем месте!

И теперь, интерполируя этот гипотетический пример на код, у нас вместо 2 уже 4 инструмента которые надо знать, использовать и думать в каком сценарии какие из них лучше применять. А на проекте есть код написанный старыми методами и теперь надо думать еще и о том, чтобы мигрировать или переписывать их на новые, либо закрыть глаза на принцип единообразности и позволить на одном проекте существовать как старому, так и новому способу записи одного и того же. А потом еще старые методы сделают deprecated, сиди и выпиливай их. А завтра под соусом стремления к сферическому чистому и читаемому коду, они придумают еще один способ записи условий в HTML. Дай бог чтобы об обратной совместимости кто-то думал и не выпиливал в будущих версиях старые методы. По сути это мелочь, одна из тысячи, но из таких мелочей складывается весь рабочий процесс.

Может конечно этот взгляд не очень популярен, но я считаю что:

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

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

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

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


  1. ivankudryavtsev
    02.11.2023 13:25

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

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

    Есть стратегия, основанная на «deprecated» предупреждениях, скажем в течение 2х версий, а потом выпиливании.

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


    1. D_menty Автор
      02.11.2023 13:25

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


    1. muturgan
      02.11.2023 13:25

      Да в жс относятся к обратной совместимости как мало где) Даже баг typeof null оставили в угоду Ей. Видите ли слишком много сайтов в интернете написано с расчетом на это недоразумение.


      1. nin-jin
        02.11.2023 13:25

        А typeof NaN === "number" вас не смущает?


        1. muturgan
          02.11.2023 13:25

          Не смущает, это корректное поведение. Если не в соответствии с чьим то рассуждениями то в соответствии со спецификацией.


          1. nin-jin
            02.11.2023 13:25

            Так и на typeof null не жалуйтесь.


  1. radtie
    02.11.2023 13:25

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

    А я вот несогласен, да, с точки зрения бизнеса этот тезис верен, но с точки зрения инструмента, это ведет к раздуванию и к торможению в развитии.

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

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

    Как по мне, раз в 3-5 версий стоит обрывать совместимость, чтоб развязывать себе руки.


    1. D_menty Автор
      02.11.2023 13:25
      +1

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


      1. ivankudryavtsev
        02.11.2023 13:25

        Ну вот они вместо Angularjs выпустили Angular и это был большой геморрой.


      1. radtie
        02.11.2023 13:25

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


    1. themen2
      02.11.2023 13:25

      Например? Что надо выбросить и что включить?


      1. D_menty Автор
        02.11.2023 13:25

        Тоже интересно было бы послушать


      1. nin-jin
        02.11.2023 13:25

        Выбросить: rxjs, свои модули, дайджест

        Добавить: сигналы, нативные модули, onpush по дефолту.


        1. themen2
          02.11.2023 13:25

          Почему? А то выглядит как просто мнение;)


          1. nin-jin
            02.11.2023 13:25

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

            Ещё не плохо бы async-pipe убрать в пользу Suspense.


      1. radtie
        02.11.2023 13:25

        imho:

        • change detection, zone, раз уж есть AOT, rxjs и сигналы

        • кастомный неоднозначный синтаксис шаблонов, или и дальше двигаться в сторону Razor (asp.net), или, простихоспаде, TSX, сколько костылей с тайп-чекингом шаблонов уберет

        • возможно модули, как минимум не lazy

        • ну и еще по мелочи


  1. balandinve
    02.11.2023 13:25

    Не упомянули про инструмент миграции.

    На сколько он справится.


    1. D_menty Автор
      02.11.2023 13:25

      У меня были проблемы миграции, причем неоднократно. Раз были и были не только у меня, значит фигово он справляется... А если надо сразу на 5 версий вперед обновить? Есть такие инструменты? Когда иной раз и на одну без проблем не получается


  1. nin-jin
    02.11.2023 13:25

    Неужели это не очевидно тем кто разрабатывает фреймворки?

    Так вы не используйте фреймворки от проф непригодных авторов. Вот, в $mol, как писали 8 лет назад так:

    <= Syntax_example $mol_section
        title \No @if, #else, &and "other" \escaping
        content <= syntax_example /
            <= Bid $mol_paragraph title \Use mol!
            <= Use_mol $mol_check_box checked? <=> use_mol? true
            <= Yes $mol_paragraph title \Yes!
            <= No $mol_paragraph title \Nooooooo!
    @ $mol_mem
    syntax_example() {
        return this.use_mol() ? [
            this.Use_mol(),
            this.Yes(),
        ] : [
            this.No(),
            this.Use_mol(),
        ]
    }

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


    1. D_menty Автор
      02.11.2023 13:25
      +3

      Значит они все правильно делают) Однако с таким синтаксисом или пиаром видимо им не удалось снискать популярности у массового фронтендера. Делают все правильно, но изначально сделано по первому впечатлению довольно дурно. Но менять ни в коем случае нельзя синтаксис. Надо выпускать новый фреймворк


  1. themen2
    02.11.2023 13:25
    +3

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


    1. D_menty Автор
      02.11.2023 13:25

      Именно так. Если не будет движения, нечего будет показать на презентациях руководству и заказчикам. А значит не будет денег. Вот и приходится выдумывать всякое. Главное чтобы было побольше красивых английских словечек)


  1. kemsky
    02.11.2023 13:25

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


  1. alexnozer
    02.11.2023 13:25
    +1

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

    В итоге у нас доктайпы, чтобы включить нужный режим парсера, все старые элементы (`marquee`, frame, font, big и тд) все ещё работают, код движков все ещё содержит тонны логики по их обработке. Скоро у нас будет select и selectlist - одно и то же, но одно стилизуется, другое - нет. У нас есть b и strong, i и em, вроде одно и то же, но есть нюанс. И тд и тп.

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