Когда писал код очередной функции по форматированию даты, поймал себя на мысли, что делаю это уже с стотысячпятисотый раз. Разные ЯП, разные проекты, разные предметные области - а делать приходится одно и то же. Шлёпать формы на фронте, пилить CRUD на бэке, гонять между ними XML/JSON - вот и всё веб-программирование, по большому счёту. Раз за разом делаешь очень похожую работу, которая всегда чуть-чуть отличается от того, что было ранее.

И казалось бы, ведь можно же сделать библиотечную функцию по форматированию даты в виде “06/20 09:25” и использовать её во всех проектах. Или хотя бы во всех своих проектах. Но нет, новый проект, нужно отформатировать дату и ты опять применяешь копипасту, перенося код из последнего проекта в самый-самый последний. Может быть, называешь функцию чуть по-другому, или помещаешь её рядом с другими функциями, а не так как было в предыдущем проекте. Но ты не используешь “универсальную библиотеку по форматированию даты-времени во всех форматах”, типа moment или luxon. Потому что их функционала (а вернее, “веса”) тебе “замного будет”.

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

И тут у меня в памяти всплыла вот эта статья про сети Колмогорова-Арнольда. Краткий пересказ - “дело не в узлах, дело в связях между ними”. В веб-программировании вся сложность кроется не в том, какие вьюшечки как делать, какую библиотеку компонентов использовать и какой контракт у эндпоинта (это всё можно накопипастить из других проектов или даже в рамках одного проекта), а в том, как это друг с другом связано. Можно на зубок знать, что такое вычислительная сложность алгоритмов, но так ни раз и не столкнуться с необходимостью применить это знание. На вебе нет, как правило - нет, сложных алгоритмов.

Веб-приложения - это не про “сложно”, веб-приложения - это про “много”. А вот уже эксплуатация веб-приложений - вот это про “сложно”. Поэтому и появилась потребность в DevOps, микросервисах и микрофронтэндах, облаках и масштабировании. И поэтому же, на мой взгляд, “толстые клиенты” (IndexedDB, local storage, service worker и cache storage) в веб-разработке будут становиться всё популярнее.

P.S.

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

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


  1. nin-jin
    20.06.2024 09:00
    +1

    А вот если бы у вас в памяти всплыли эти статьи, то сего поста бы и не появилось:


  1. kosmonaFFFt
    20.06.2024 09:00

    Всегда брал, и тащил какую-нибудь большую крутую универсальную библиотеку, даже если оттуда мне нужна только одна функция.


    1. flancer Автор
      20.06.2024 09:00
      +1

      Да, это известный паттерн поведения при разработке на JS.


  1. SuperCat911
    20.06.2024 09:00
    +1

    А может дело не в связях, а в оформлении и хранении ранее написанного кода?

    Я решаю это довольно просто: создаю репозиторий (публичный или приватный разницы нет) и оттуда все написанное добро подтягиваю.

    Можно и в публичный npm публиковать свои ведосипеды. Так даже лучше, я думаю, так как социальная ответственность возникает, что ли. Приходится документировать код, писать тесты. И как начинаю новый проект, делаю npm install личных библиотек, и не приходится заново писать эти функции. Лишнее все тришейкаю через esbuild или иные утилиты. ES-модули рулят, короче.


    1. flancer Автор
      20.06.2024 09:00

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

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

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

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

      И, да - es-модули рулят (y)


      1. nin-jin
        20.06.2024 09:00
        +2

        Забавно, когда показываешь человеку решение всех его проблем, а он делает вид, что ничего не услышал, и продолжает с упоением рассказывать про эти проблемы. Лучше быть экспертом в создании проблем, чем новичком в их решении?


        1. flancer Автор
          20.06.2024 09:00

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

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

          И я, к тому же, предпочитаю "чистый JS". Просто не люблю транспиляцию, и всё тут. А ваш МАМ - "директория, внутри которой могут быть исходники на самых разных языках" (с) Стар я уже, изучать "самые разные языки", мне бы в одном ЯП удержаться ;)


          1. nin-jin
            20.06.2024 09:00

            Примечательно, что именно в МАМ вам и не нужна транспиляция для сборки бандла из исходников на чистом JS.


            1. flancer Автор
              20.06.2024 09:00

              не нужна транспиляция для сборки бандла из исходников на чистом JS

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

              Зачем же ещё производители воткнули гигабайты и гигагерцы в оконечные устройства юзеров, как не для моего удобства? :)


              1. SuperCat911
                20.06.2024 09:00
                +1

                Если перед строкой с html ставить /* html */, то будет вообще красота (подсветка html в коде js).

                https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html


                1. flancer Автор
                  20.06.2024 09:00

                  Походу, это рецепт для VSCode :( Я добавил, но в Chrome ничего не изменилось:

                  а PhpStorm и так подсвечивал:

                  но за подсказку спасибо :)


                  1. SuperCat911
                    20.06.2024 09:00
                    +1

                    Для VSCode, верно. Пожалуйста!


              1. nin-jin
                20.06.2024 09:00

                Ох уж эти эксперты, которые не знают, что из esm до сих пор нельзя собрать бандл без транспиляции.

                Я уж молчу о сомнительном удобстве IoC через DI, вёрстки без подсветки синтаксиса, и развесистых JSDoc-ов, вместо нормальных тайпингов.


                1. flancer Автор
                  20.06.2024 09:00

                  А я и не говорил, что я эксперт в сборке бандлов, скорее я говорил наоборот - что предпочитаю обходиться без них :)

                  И чем это вам не угодил "IoC через DI"? Какой тип IoC используете вы?

                  Вёрстка, кстати, в PhpStorm подсвечивается - у меня и скрин выше приведён.

                  Остаётся вопрос JSDoc'ов, но из двух зол (JSDoc'и или транспиляция) я выбрал первое, а вы - второе. Так что это моя плата за возможность видеть везде один и тот же код. Вы привыкли к транспиляции, а я - к JSDoc'ам.


                  1. nin-jin
                    20.06.2024 09:00
                    +1

                    Контекст Окружения

                    Сорсмапы вроде бы уже изобрели.


                    1. flancer Автор
                      20.06.2024 09:00

                      Я просто когда-то давно читал "Dependency Injection, Principles, Practices, and Patterns", так там "Ambient Context" назван анти-паттерном. Вы, наверное, читали другую книгу - "Ambient Context, Principles, Practices, and Patterns" :)


                      1. nin-jin
                        20.06.2024 09:00

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


                      1. flancer Автор
                        20.06.2024 09:00

                        Я так понимаю, что одна звёздочка этой "глупой книге" на Амазоне от вас прилетела :)

                        Лично мне "IoC через DI" более чем удобно. Я и до середины возможностей этой технологии пока не добрался. Может быть потом, когда уткнусь в её ограничения, я переосмыслю накопленный опыт и перейду к "Контексту Окружения", но пока так.


      1. SuperCat911
        20.06.2024 09:00
        +1

        Я говорю о том, что полностью решил проблему разрастания кода. Даже ничего копипастить не нужно. Причем я пишу код на чистом js с использованием jsdoc с typescript (директива в коде @ts-check). У меня код самый нативный при этом. Модули можно запускать со сборкой и без нее.

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

        И всегда пишу тесты для сорсов и для бандлов.