Анализ того, что является правильным инструментом для работы, прежде чем совершать годы сожалений

В далекой-далекой галактике

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

Сейчас мы начинаем новый проект в Anyline GmbH. Раньше у нас было много относительно небольших репозиториев. Некоторые из них были для микросервисов, которые все еще живы и здоровы, другие оставались в застое больше года. После утомительного рефакторинга, проведенного моими коллегами, мы смогли сократить это число до чуть менее 100 репозиториев. Но проблема осталась: у нас было много дублирования кода между пакетами, сложное развертывание критических изменений и довольно много мест, где можно было найти части документации, применимые к нескольким сущностям.

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

  • Рабочие пространства из чистой пряжи за их минимализм
  • Nx.dev, как один из самых зрелых проектов в экосистеме JS/TS.
  • Turborepo как относительно новое (выпущено в конце 2021 г.), но многообещающее решение, поддерживаемое Vercel.

Что касается требований, то мы составили такой список:

  • 📚 Управление зависимостями верхнего уровня для JavaScript/TypeScript
  • 🔍 Единая конфигурация линтинга
  • 🏗 Инкрементальные сборки
  • 📦 Кэширование шагов сборки, в идеале между средами разработки
  • ⏳ Готовая перезагрузка горячего модуля для приложения Next.js для импортированных пакетов
  • 😎 Общий «опыт разработчика»

К сожалению, с рабочими пространствами по умолчанию нам пришлось бы реализовывать большинство из вышеперечисленных элементов самостоятельно, поэтому выбор сузился до nx.dev против turborepo.

Итак, вот оно…

Управление зависимостями

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

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

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

Nx 1 — Турборепо 0

Равномерный линтинг

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

Turborepo также по умолчанию создает пакет с конфигурацией ESLint, от которого могут наследоваться другие пакеты.

Nx 2 — Турборепо 1

Кэширование и инкрементные сборки

Nx использует два основных типа кэширования:

  • Локальный, что является довольно понятной концепцией: вы запускаете сборку, артефакты кэшируются как целиком, так и частичные артефакты сборки, а при следующей сборке у вас есть возможность повторно использовать свою работу.
  • Распределенная, которая основана на предыдущей модели, но также синхронизирует кеши между совместимыми средами разработки, что делает даже первую «локальную» сборку такой же быстрой, как и сборки с существующими кешами.

К сожалению, распределенное кэширование — это вариант SaaS, предоставляемый nx.dev.

Что касается турборепозитория, то он также поддерживает локальное и удаленное кэширование. И снова, как и в случае с nx, удаленное кэширование доступно как часть решения SaaS, на этот раз на базе Vercel.

В целом оба продукта находятся на одном уровне в отношении кэширования.

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

Nx 3 — Турборепо 2

Горячая перезагрузка

И nx, и turborepo отлично работали с горячей перезагрузкой модуля Next.js. Хотя могут быть некоторые обходные пути, которые нужно будет реализовать с turborepo, в целом опыт работы с обоими инструментами довольно хороший.

Опыт разработчиков

Это в основном субъективная тема, поэтому все здесь следует воспринимать с долей скептицизма. Nx поставляется с довольно зрелым инструментом командной строки, а также с плагинами VS Code и JetBrains. Со стороны Turborepo по состоянию на лето 2022 года плагинов для IDE не существует, и, похоже, на данный момент это официальная позиция разработчиков.

Кроме того, nx обеспечивает гораздо более развитую экосистему, поскольку он существует на рынке уже почти 5 лет. Вероятно, Turborepo когда-нибудь доберется до этого уровня, но сейчас он все еще находится в довольно ранней стадии своей жизни.

Наконец, по моему опыту, сборки nx занимают меньше времени как за счет инкрементных сборок, так и за счет распределенного (и локального) кэширования. Кроме того, я чувствовал, что было бы более просто и «нативно» добавлять пакеты на языках, отличных от JavaScript или TypeScript.

Nx 4 — Турборепо 2

Краткое содержание

Я считаю, что nx обеспечивает лучшую производительность и удобство для разработчиков. Turborepo еще слишком молод, и его экосистема только начинает созревать. Вероятно, через пару лет он составит сильную конкуренцию другим решениям, так как сообщество уже проявляет к новому инструменту большую любовь. Но пока я считаю, что лучше придерживаться того, что уже работает и является «боевым».