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

Теперь, когда я стал более опытным, я все еще думаю, что переход на гибрид с мобильными приложениями - хорошая идея, но я думаю, что большинство людей уговаривают делать это неправильно и / или делать это по неправильным причинам. Люди делают ошибку, потому что дело не в модных словах. Речь не идет о переходе на Cordova, Flutter, React Native, Xamarin или какой-либо конкретный фреймворк.

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

Задний план

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

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

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

Может ли автоматическое тестирование решить эту проблему? Не совсем. Если вы напишете автоматические тесты для всех своих клиентов и запустите их в CI, вы узнаете, когда было внесено неверное изменение кода. Это во многом поможет предотвратить попадание полученных ошибок (их будет много) в рабочую среду. Но взамен вы все равно потеряете много рабочего времени на внесение изменений, которые пройдут все тесты. Автоматические тесты помогают вашим клиентам, а не вашим инженерам. Вы также потеряете время на написание тестов. Имейте в виду, что для гибридного веб-приложения и мобильного приложения мы говорим о тестах пользовательского интерфейса, которые, как правило, являются наиболее дорогостоящими и обременительными в обслуживании.

Поймите модные слова

Оценивая новейшие технологии, вы должны попытаться выяснить, для кого на самом деле эта технология и как она соотносится с вашим текущим положением.

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

Взять, к примеру, Apache Cordova. Cordova позволяет вам взять ваш веб-сайт и упаковать его в мобильное приложение. Эта технология позволяет вам создать веб-сайт, а затем обратиться к своему начальнику, клиентам или инвесторам и сказать: «У нас есть мобильное приложение». Но по причинам, описанным ранее в статье, это замедлит вас в долгосрочной перспективе. Вы пытаетесь поделиться ВСЕМ кодом сразу, поэтому теперь вам нужно начать втискивать изменения для разных платформ в одну и ту же кодовую базу. Вам понадобятся всевозможные динамические переключатели, переключатели, таблицы и т. Д. Кордова - это кратчайший путь к худшему виду ада общего кода, в котором находятся многие компании.

Что забавно, возможно, вы перешли на эту статью, потому что думаете о «переходе на Кордову». «Переключение», например, у вас уже есть мобильное приложение, но вы хотите сделать его приложением Cordova, потому что вы думаете, что это может снизить ваши расходы. Рискуя показаться зашитой пластинкой, я говорю вам, что произойдет обратное. Ваши затраты увеличатся, а скорость итераций снизится по сравнению с поддержкой отдельных приложений, как в моей старой компании, в которой сотни инженеров занимали год для отправки незначительных обновлений. Попытка использовать один и тот же исходный код дважды снижает краткосрочные затраты, но увеличивает долгосрочные затраты. То есть, если вы не сделаете это правильно.

Как делиться кодом в 21 веке

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

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

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

И React, и Angular (новый) следуют принципам проектирования с высокой степенью компонентности. Сам компонент следует объектно-ориентированным принципам с выделенными формальными механизмами ввода и вывода. В Angular даже есть встроенная инъекция зависимостей для этих целей.

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

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

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