Работая с монорепозиторием, ты наверняка слышал о наборе инструментов Nrwl Nx. Если вкратце, то Nx ускоряет и упрощает работу с монорепой, снабжает полезными утилитами. Держи документацию. Часто работа с Nx заканчивается на имеющихся дефолтных настройках. Все остальное остается черным ящиком. Время сборки проектов начинает расти, а причины так и остаются неизвестными. Может, есть что-то, что способно улучшить работоспособность монорепы и хотя бы частично решить проблемы? Предлагаю отправиться на изучение официальной документации и поискать лайфхаки вместе со мной. Ниже приведу список полезных инструментов и механизмов, вкратце расскажу о них и дам ссылки для детального изучения.  Итак, что же ты мог упустить при работе с Nx: nx run-many dependency graph + nx affected nx-enforce-module-boundaries es-linting computation cache nx cloud buildable libs  Есть монорепозиторий с: приложениями: App1, App2, App3 библиотеками: Lib1, Lib2, Lib3. Вот ссылка для освежения в памяти этих понятий. На графе представлено их взаимодействие друг с другом.   Затем мы вносим изменения в Lib3: пилим новую фичу (или докидываем еще больше багов в код, тут как повезет), и в конце всего этого хотим проверить, а не сломали ли мы чего своими правками, надо бы запустить тесты.  Так как сломаться могло что угодно, то лучше прогнать тесты по всей монорепе.  Начинаем выполнять: nx test Lib3nx test App1nx test App2...Стоп. Слишком долго, попробуем иначе. Вот мы и встретили первое упрощение нашей работы (штука популярная, но мало ли, кто не знал). Команда run-many выполняет задачу параллельно для нескольких проектов, можно указать как все (--all), так и какие-то конкретные (-p  App1).  В дефолтном состоянии команда выполняет параллельно 3 задачи, это конфигурируется с помощью parallel опции (--parallel=6). Выполним nx run-many --target=test --all для нашего случая. Тесты будут запущены для всего: App1, App2, App3, Lib1, Lib2, Lib3. Работоспособно, но если изменения повлияли только на один проект? Не хочется лишний раз прогонять все тесты.  У Nx есть решение для этого: команда nx affected Запуская nx affected --target=test, будут выполнены тесты только для Lib3 и App3. С Lib3 все понятно, мы туда внесли изменения. Но откуда взялось App3?  Все дело в dependency graph. По сути, граф в начале статьи и является таким графом зависимостей. Визуализировать у себя его можно с помощью команды nx graph.При запуске nx affected Nx под капотом строит такой граф из имеющихся проектов, запускает анализ изменений в коде и определяет список затронутых изменениями либ/приложений. Отдельной статьи заслуживает вопрос, а как именно Nx анализирует изменения? Вероятно, руки дойдут, и статья будет. Либо можно самостоятельно ознакомиться с source файлами.Отлично, теперь прогон тестов занимает не так много времени. Но что может нам подпортить производительность? Пока в монорепозитории царят циклические зависимости, пользы от nx affected становится с каждым разом все меньше. Настало время рефакторинга!Чтобы было удобнее отслеживать циклические зависимости, используем следующее правило линтера, которое подсветит все проблемные места: @nrwl/nx/enforce-module-boundaries.Внимательно изучи документацию, правило имеет разные способы конфигурации.   Супер. Теперь мы запускаем таски только на нужных проектах и не имеем циклических зависимостей. А есть какой-нибудь кэш?  Конечно! Nx computation cache. Здесь все просто: nx перед запуском таски вычисляет хеш. Если такой уже существует в кэше, то повторно выполняться таска не будет, результат возьмем из кэша. Список кэшируемых тасок может настраиваться. Что учитывается при построении хеша: source файлы и зависимости конфигурация версии внешних зависимостей флаги cli версия ноды (и прочие райнтайм значения) Можем ли мы как-то кастомизировать это? Да, без проблем! Хеш для линтера, например, может учитывать только исходный код и глобальный конфиг. Подробней здесь.А где находится кэш? Его стандартное расположение — node_modules/.cache/nx. И даже это можно изменить. Если в твоей команде нет жадных коллег, то можно с ними обмениваться кэшем. Для этого нужно либо реализовать собственный кэш, либо воспользоваться готовым решением от Nx — Nx Cloud. При выполнении таски сперва проверяется наличие хеша в локальном хранилище, а если использовать Nx cloud, то поиск выполняется и в удаленном кэше. То есть запускаешь тесты у себя, а твои коллеги могут воспользоваться этим результатом без затрат времени на повторное выполнение. Перейдем к пункту со звездочкой? Как мы знаем, в качестве target для библиотеки может быть lint или test. Отдельно взять и сбилдить библиотеку просто так мы не можем, только с помощью билда приложения, которое ее использует. Обычно это происходит так: при выполнении build/serve приложения, webpack отдельно билдит зависимости и кладет их к бандлу приложения.  Для небольших проектов это еще работает, но с увеличением кодовой базы продолжительность build/serve будет только увеличиваться, здесь нам помогут buildable libs.С помощью опции buildable: nx g @nx/angular:lib Lib1 --buildable мы даем возможность Lib1 быть так сказать buildable и билдиться отдельно от приложения. Данная опция поддерживается не только для Angular, но и для React, NestJs, Node. Теперь при повторном выполнении build/serve не придется повторно билдить Lib1, так как Lib1 прекомпилируется и в случае наличия кэша берется из него. Хочу поблагодарить тебя, читатель, что уделил время и дочитал статью до конца. Мы рассмотрели некоторые возможности и механизмы Nx, которые могли быть пропущены при знакомстве с ним. Имея в своем арсенале хотя бы такое минимальное представление об этом, уже можно наметить пути ускорения работы с Nx у себя в монорепе.  Возможно, следующие статьи будут посвящены более детальному обзору, если будет потребность. А пока расскажите, удалось узнать что-то новое из статьи?  Frontend developer