Бенчмарк технологий и инструментов

Примечание.

Следующий тест может быть немного устаревшим, когда вы будете читать эти строки, так как он был сделан в апреле 2022 года. Монорепозитории сейчас на пике популярности, и все происходит быстро.
С тех пор многое произошло, обслуживание Lerna теперь принадлежит Nrwl (команда разработчиков Nx), и почти вся документация по инструментам стала более качественной и ясной (особенно Lerna и Lage).

Эталонная методология:

  • перечислить целевые функции и требования
  • поиск временных инструментов
  • тестирование инструментов
  • принятие решений

Возможности инструментов монорепозитория

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

Мы перечислили их здесь:

  • Оркестровка задач [быстро]
  • Кэширование локальных/распределенных вычислений [быстро]
  • Обнаружение уязвимого кода [быстро]
  • Обнаружение (анализ рабочей области) [понятно]
  • Согласованность инструментов [управляемая]
  • Совместное использование кода [управляемый]
  • Генерация кода [управляемая]
  • Определение владения кодом и ограничения [управляемый]

При этом у нас также были ожидания относительно документации, эргономики разработки и зрелости решений.

Инструменты протестированы

Эталон

Выявить, классифицировать и сравнить инструменты было нелегко, поскольку требования традиционно распределяются в отдельных инструментах: системах построения, менеджерах пакетов и других. Их функциональные возможности частично совпадают и не обязательно предназначены для воплощения философии монорепозитория per see.

Короче говоря, вот наши рекомендации для каждого инструмента:

Турборепо:

  • Делает одно (масштабирование выполнения задач), и делает это хорошо.
  • Низкая стоимость внедрения (возможно постепенное внедрение).

Возраст:

  • Очень похоже на Turborepo
  • Используйте его для оптимизации выполнения конвейеров задач.
  • Низкая стоимость внедрения

Базель:

  • Отлично подходит для команд разработчиков, использующих несколько ОС.
  • И несколько языков (Java, Go, C++, Android, iOS).

Nx:

  • Гибкое и масштабируемое решение для выполнения задач.
  • Позволяет инкапсулировать лучшие практики команды благодаря настраиваемым генераторам кода.
  • Предоставляет официальные и общественные интеграции/плагины (NextJS, NestJS, React, Angular…)
  • Средняя стоимость внедрения (требуются адаптации package.json, jest.config, .eslintrc, webpack.config и tsconfig).

Лерна:

  • ⚠️ Команды Nrwl взяли на себя управление.
  • Хорошо подходит, если вы хотите опубликовать свои пакеты в менеджере пакетов.
  • Каждый проект будет содержать свои зависимости (возникает проблема зависимости от алмаза).

Выбор

В приведенной выше таблице нет ничего удивительного в том, какой инструмент мы в итоге приняли: Nx 🎉

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

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

Вот основные способы, которыми Nx отвечает на потребности наших команд в масштабировании:

Структура кода

[масштабируемый понятный управляемый]

myorg/ # workspace
├── apps/ # applications = 20% of the code
  ├── app1
  ├── app2
  ├── ...
├── libs/ # libraries = 80% of the code
  ├── lib1
  ├── ...
├── tools/ # commands
├── workspace.json # list applications
├── nx.json # configures nx cli
├── package.json
└── tsconfig.base.json # ts conf and aliases for resolving code sharing

Предлагаемая структура кода предлагает следующую ментальную модель:

Разделение кода:

  • 20% в папке приложения [понятно]
  • 80% в папке libs [понятно]
  • данные (типы, доступ к данным…) [масштабируемый понятный]
  • Пользовательский интерфейс (общие компоненты рендеринга) [масштабируемый, понятный, управляемый]
  • функции (специфические компоненты функций) [масштабируемый понятный]
  • utils [масштабируемый понятный]

Помимо этой структуры кода, репозиторий содержит общие файлы конфигурации в корневой папке (т. е.: tsconfig.json, eslint, webpack.config…) и встраивает версию каждого из них в библиотеки приложений. Они расширяют корневую конфигурацию и позволяют настраивать каждое приложение или библиотеку.

Это гарантирует, что глобальный набор лучших практик будет определен на уровне главы, а конкретные варианты использования будут определены на уровне отряда. [масштабируемый управляемый]

Запуск задач

[масштабируемый понятный управляемый]

Каждое приложение и библиотека включают файл project.json, в котором перечислены все возможные команды, цели и задачи.

$> nx run app:build #command
build #target
header:build #task

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

Кэширование вычислений задач

[быстро масштабируется]

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

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

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

Теги обеспечивают ограничения графа проекта

[право собственности понятно]

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

Инкапсулируйте лучшие практики и ускорьте рабочий процесс разработки с помощью генераторов

[масштабируемый управляемый]

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

Выводы

Наш тест позволил нам выбрать Nx, который больше всего соответствовал нашим текущим потребностям и контексту.

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

Далее идет фаза реализации!