Создание серии веб-приложений: выпуск № 2

Думаю, первое техническое решение при создании веб-приложения: где оно будет жить? Традиционно было 2 варианта: монорепозиторий или мультирепозиторий. Но я видел это, и возможно иметь гибрид. Используйте монорепозиторий для некоторых проектов, а также несколько других репозиториев, каждый для одного проекта. Я выбираю модель монорепозитория, но я всегда могу перейти на гибридную модель и иметь несколько проектов в собственном репозитории, если что-то изменится. Далее следует, почему и как это может выглядеть.

Но сначала небольшое отступление.

Что такое монорепозиторий?

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

Еще несколько определений следующего:

  • Веб-приложение: пользовательский интерфейс, с которым взаимодействует пользователь.
  • Проект: исходный код приложения.
  • Приложение: запущенный и работающий исходный код. Это грубое объяснение, но оно кажется ясным. Это может быть веб-сервер, база данных, сервер Redis и т. д.

Почему стоит выбрать монорепозиторий?

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

  • Логика разбросана повсюду, и сложно найти код и понять, как все работает.
  • Дублирование кода, конфигурации, ресурсов и т. д.
  • Рефакторинг и реализация этих кросс-проектов сложны.
  • Управление зависимостями между проектами может быть затруднено при наличии нескольких уровней зависимости. Пакет D обновлен, затем необходимо обновить пакеты C, B, чтобы пакет A мог получить новые версии пакетов C и B. Умножьте это на 5 пакетов, и все станет сложнее.

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

  • Исходный код, зависимости разработки и конфигурация могут совместно использоваться пакетами.
  • Разработчикам проще перейти к другому проекту, понять код и внести изменения.
  • Опыт разработчика (DX) часто лучше. Если разработчики довольны работой, это обычно приводит к созданию лучшего программного обеспечения.
  • PR может описывать целостное представление об изменении: серверная часть, внешний интерфейс, база данных и т. д. Это может помочь разработчикам лучше понять общую архитектуру системы и происходящие изменения.
  • Легче ориентироваться в нескольких проектах. Это похоже на то, как изменение папки при наличии проектов в разных репозиториях обычно подразумевает постоянное переключение между окнами и IDE.
  • Настроить среду разработки несложно. Если вы когда-нибудь пытались использовать ссылку npm в нескольких проектах и ​​заставить работать webpack, вы понимаете, о чем я говорю. Конечно, вы можете заставить его работать, но это боль. Например, если вы используете Lerna, вы можете сделать это одной командой.
  • Атомарные межпроектные коммиты: все проекты нормально собирались и работали вместе на коммите X.
  • Поиск по проектам
  • Инструменты могут запускаться в проектах, например, статический анализ кода, сканирование безопасности, линтеры и т. д.

Один лингва-франка: TypeScript

Поскольку я создаю веб-приложение с нуля, у меня есть прекрасная возможность использовать один и тот же язык программирования в разных проектах. Возьмем пример: проверка пользовательского ввода. Когда пользователи регистрируются в веб-приложении, им нужно будет указать свое имя, а максимальная длина имени составляет 250 символов. Какое-то произвольное число. Это очень просто, но потерпите меня. Проверка ввода выполняется на стороне клиента и на стороне сервера, и обычно разработчики дублируют логику для проверки имени пользователя. Если когда-нибудь в будущем API изменится, то потребуется обновить как минимум два проекта. Но если я использую один и тот же язык программирования в обоих проектах. У меня мог бы быть класс Profile (простой класс JavaScript), который содержит всю логику проверки для создания действительного объекта профиля. Затем я мог бы повторно использовать этот класс в клиентских и серверных проектах. Это небольшой пример, но представьте, что вам нужно сделать это для большого количества входных данных в разных форматах и ​​даже больше данных, которые будут иметь особые требования в соответствии с бизнес-правилами приложения. Изоляция основной логики приложения от всего остального поможет создать надежное и удобное в сопровождении приложение.

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

Проект

Однажды я где-то прочитал, что хороший архитектор программного обеспечения умеет откладывать решения до тех пор, пока не будет доступно достаточно информации. Итак, я приму решения, которые могу, и отложу те, о которых у меня недостаточно информации. Я создаю веб-приложение, я знаю, что в какой-то момент мне понадобится база данных и API, но сейчас у меня недостаточно информации, чтобы принять решение, и мне действительно не нужна база данных и API. чтобы приступить к созданию пользовательского интерфейса. Так что мне не о чем беспокоиться. Другой пример: я знаю, что мне, вероятно, понадобится какой-то фреймворк пользовательского интерфейса (NextJS, Gatsby и т. д.), но я думаю, что ядро ​​пользовательского интерфейса не должно заботиться ни о каком фреймворке. Поэтому я буду строить его вне каких-либо рамок в проекте под названием «UI». Что я знаю точно, так это то, что я буду использовать React. Это решение, для которого у меня достаточно информации. Без лишних слов, вот как это выглядит сейчас:

В следующем посте я подробно объясню каждую папку и логику размещения всех файлов конфигурации.

Спасибо за чтение!