Size: a a a

JavaScript.Ninja

2020 March 05

IK

Illya Klymov in JavaScript.Ninja
Oleg Postnikov
Всем привет, у меня скорее менеджерский вопрос.

Вопросы:
1. Как объяснить менеджеру, что нужно переписать все приложение на современный стэк технологий?
2. Возможно ли как измерить ценность от смены фреймворка для конечного пользователя продукта?
3. Возможно, вы знаете какие-нибудь статьи о том, как принимать решения о миграции с менеджерской точки зрения? Я нахожу в интернете только материалы про технические преимущества в миграции на тот или иной стэк технологий.

Контекст:
Работаю фронтендщиком в продукте, по скраму, в команде с еще не сформированными процессами.

Фронтенд в этом продукте - это легаси SPA, написанный не текущей командой разработчиков, и у него есть некоторые проблемы:
1. Он написан на JQuery, со всеми вытекающими
2. При проектировании проекта не предвидели объема функционала, который необходим сейчас
3. Торопились, когда писали, в связи с чем применили не самые хорошие архитектурные подходы.

Из-за этих проблем наша команда сейчас испытывает следующие боли:
1. Для создания простого компонента необходимо большое количество boilerplate кода
2. Приходится поддерживать постоянно ломающиеся кастомные решения типичных фронтедерских задач.
3. Задачи выполняются долго, а когда выполнятся оставляют большой хвост из багов, которые никто не отловил.

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

Проблема возникла в коммуникации с Product Owner, он не против миграции, но его в первую очередь интересует ценность, которую получит пользователь конечного продукта. И просит привести КАКИЕ-НИБУДЬ статистические показатели, по которым он сможет принять решение:
1. Стоит ли это делать?
2. Когда это нужно делать?

Очевидные ответы в духе:
1. Меньше кода нужно написать => Быстрее делается задача => Увеличивается Time To Market
2. Внедрение типизации => меньше багов на продакшене

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

OP

Oleg Postnikov in JavaScript.Ninja
Baxxter
И тем более не очень понятно как вы целиком хотите рефакторить весь легаси без автотестов. Начать стоит именно с тестов, хотя бы на свежий код
Вы правы, никто не планирует делать переписывать весь проект сразу. Сложность возникает в обосновании того, что этим стоит заниматься.
источник

IK

Illya Klymov in JavaScript.Ninja
Я вон выше простыню написал )
источник

OP

Oleg Postnikov in JavaScript.Ninja
Illya Klymov
Я вон выше простыню написал )
Спасибо, читаю
источник

IK

Illya Klymov in JavaScript.Ninja
сейчас вернусь еще раз - расскажу о своем опыте с типизацией
источник

IK

Illya Klymov in JavaScript.Ninja
Итак, опыт "с пылу с жару" (на бэке, но тем не менее)
Дано:
- проект task management system для javascript.ninja -  штука, которая выдает студентам задания на курсах, отслеживает статус решений в GitLab и так далеею Проект начинался с одной таблички в БД, сейчас их под 10 и скоро будет больше, начали сыпаться проблемы "а вот тут не учли что может быть null" и тому подобное - типизация нам поможет!
- я, худо-бедно имеющий опыт во Flow/TypeScript (это важно, потому что обучение типизации внутри команды - достаточно нетривиальная задача)

Беру код, начинаю портировать на typescript. Обнаруживаю, что пользы от этого мало - моя ORM - objection по определенным причинам не позволяет отслеживать загрузку связанных сущностей, в итоге ты никогда не можешь быть уверен - task.author null или не null - он мог быть загружен как связь или нет. Вывод - по всему коду расставлять дополнительные проверки (что очень теряет в выразительности), забивать на это (а смысл?) или брать какой-нибудь typeORM вместо objection.

Решаю сделать третье. Беру - выясняется что на typeORM запросы которые я строил превращаются в уродские конструкции, еще и дико неэффективные с точки зрения базы данных. В итоге плюю на все и пишу runtime-контракты на валидацию нужных мест, вставляю их. При этом эти же контракты порешали бы мою проблему и в чистом JS
источник

IK

Illya Klymov in JavaScript.Ninja
Это не значит что не надо переходить на типизацию
источник

v

vasilich in JavaScript.Ninja
Кажется это тонкий намёк что типизация в ЖС это плацебо)
источник

IK

Illya Klymov in JavaScript.Ninja
Нет, ни в коем случае
источник

IK

Illya Klymov in JavaScript.Ninja
Типизация в JS/TS может быть крайне полезна, но есть ряд предусловий
источник

VN

Vladislav Navrocky in JavaScript.Ninja
Illya Klymov
Но вы забываете о затратах на содержание типизации
Интересно какие же затраты? Мы читаем код чаще чем пишем. Типизированный код намного легче и быстрее понять. Мое мнение что нетипизированный код увеличивает временные затраты, на его вычитывание, на правку багов рефакторинга на проде
источник

IK

Illya Klymov in JavaScript.Ninja
Vladislav Navrocky
Интересно какие же затраты? Мы читаем код чаще чем пишем. Типизированный код намного легче и быстрее понять. Мое мнение что нетипизированный код увеличивает временные затраты, на его вычитывание, на правку багов рефакторинга на проде
Вы можете подкрепить свое мнение цифрами? :)
источник

OP

Oleg Postnikov in JavaScript.Ninja
Illya Klymov
Развернутый ответ.

Начну с контекста (мало ли, вдруг кто-то из читающих не в теме что за хрен с горы отвечает)
У меня была 7 лет своя компания, поэтому я понимаю позиции бизнеса, сейчас я Senior Frontend Engineer в GitLab. 85% нашего кода - это jquery + bootstrap + HAML. Это больно, это тяжело поддерживать, нам приходится мейнтейнить некоторые библиотеки, которые уже заброшены создателями.

Начнем с кратких ответов на озвученные вопросы.

1. Как объяснить менеджеру, что нужно переписать всё приложение на современный стек технологий?

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

2. Можно ли как-то измерить ценность от смены фреймворка?

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

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

3. Возможно вы знаете какие-нибудь статьи о том как принимать решения о миграции?

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

Теперь о болях:
1. Для создания простого компонента необходимо большое количество boilerplate-кода

Для решения этого точно не нужен фреймворк. Любая штука для кодогенерации + чу-чуть времени выйлет дешевле

2. Приходится поддерживать постоянно ломающиеся кастомные решения

Здесь аргумент принят и логичен

3. Задачи выполняются долго, а когда выполняются остается большой хвост из багов, которые никто не отловил.

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

Теперь по-поводу главного ответа на "стоит ли это делать и когда нужно делать". Ответ "когда" банален до ужаса - когда это имеет экономический смысл. Мы бы могли сейчас застопорить всю разработку гитлаба и переписать все на Vue (мы прибыльны, у нас позитивный кешфлоу, представьте насколько бы это ускорило разработку фронта в будущем), но в масштабах грядущего IPO/Direct listing в этом году - это было бы самоубийство в глазах инвесторов.

Стоит ли делать? Здесь поможет только эксперимент. Самое правильное решение - взять задачу, которую хорошо можно изолировать от существующей системы или наиболее проблемный кусок существующей системы. Разбить эту задачу на два этапа - "подготовительный" - вам понадобится написать какое-то количества кода допустим для взаимодействия legacy-приложения и какой-вы-фреймворк-возьмете и брать его в оценку задачи неверно, и "реализация" - когда вы реализовываете этот кусок на новом фреймворке. Дальше вы смотрите на результат, и отвечаете на вопросы, насколько это удовлетворяет вашим потребностям в скорости.

Фактически, ваше решение предлает продукт оунеру прийти в казино и всё поставить на чёрное. Естественно, его эта идея немного... нервирует. Предложите ему небольшой риск в рамках 1-2 спринтов, который он может принять даже если ставка не сыграет. Вы же получите конкретные метрики.
НЕСОМНЕННО эффект будет ниже, чем если бы "все сразу" было переписано, но важно что все это понимают. И 10 денег потраченные в течение 10 спринтов гораздо выгоднее чем 100 денег потраченные в один спринт.
Спасибо за развернутый ответ, сделать эксперимент звучит как выполнимая программистская задача. Обсужу с командой. Стоит ли мне отписываться чем все закончилось?
источник

IK

Illya Klymov in JavaScript.Ninja
Oleg Postnikov
Спасибо за развернутый ответ, сделать эксперимент звучит как выполнимая программистская задача. Обсужу с командой. Стоит ли мне отписываться чем все закончилось?
Я думаю остальным будет интересно
источник

VN

Vladislav Navrocky in JavaScript.Ninja
Vladislav Navrocky
Интересно какие же затраты? Мы читаем код чаще чем пишем. Типизированный код намного легче и быстрее понять. Мое мнение что нетипизированный код увеличивает временные затраты, на его вычитывание, на правку багов рефакторинга на проде
Не могу. Но я трачу огромное время на то чтобы понять откуда же это поле в объекте взялось и что там может быть и какого оно типа..
источник

VN

Vladislav Navrocky in JavaScript.Ninja
Если этот код не я писал
источник

IK

Illya Klymov in JavaScript.Ninja
Vladislav Navrocky
Не могу. Но я трачу огромное время на то чтобы понять откуда же это поле в объекте взялось и что там может быть и какого оно типа..
Это к сожалению говорит о качестве кода. И типизация отвечает только "какого типа" а не "откуда оно взялось"
источник

IK

Illya Klymov in JavaScript.Ninja
Что же касается рефакторинга - наличие тестов закрывает этот вопрос почти полностью
источник

VN

Vladislav Navrocky in JavaScript.Ninja
Illya Klymov
Это к сожалению говорит о качестве кода. И типизация отвечает только "какого типа" а не "откуда оно взялось"
Как раз откуда взялось оно тоже отвечает. Всегда можно получить список использования по символу
источник

IK

Illya Klymov in JavaScript.Ninja
К примеру в случае с VueJS это не работает :)
источник