Beyond the Docs: The Hidden Challenges of Nx to Turborepo Migration

#monorepo#nx#turborepo#nextjs#jest

TL;DR: Миграция с Nx на Turborepo для Next.js 15 и React 19 может быть сложной из-за скрытых проблем с Jest, SVG и конфигурацией. В статье подробно разбираем шаги по переходу, включая настройку turbo.json, исправление проблем с viewBox в SVG и адаптацию Jest-конфигураций.


Введение

Monorepo — это мощный инструмент, но иногда его абстракции становятся слишком сложными. Наша команда столкнулась с этим при использовании Nx. Несмотря на его мощь, “Nx way” с кастомными исполнителями, скрытой логикой сборки и сложным кэшированием начал восприниматься как черный ящик, ограничивающий автономию команды. Мы решили перейти на Turborepo для упрощения ментальной модели: это просто раннер задач, который не мешает.


Основная часть

Проблемы с Nx

Наш setup страдал от:

  1. Сложности единого репозитория: Все приложения находились в одном репозитории, что затрудняло независимые деплои.
  2. Жесткой связности: Изменение в общей библиотеке вызывало ненужные сборки по всему проекту.
  3. Накладных расходов Nx: Кастомные исполнители и слои абстракции были сложны для отладки.
  4. Ограниченной автономии команд: Разные команды не могли работать независимо над своими приложениями.

Преимущества Turborepo

  1. Упрощенная ментальная модель: Turborepo — это раннер задач, а не фреймворк.
  2. Поддержка полирепозиториев: Каждое приложение может жить в своем репозитории, используя общую конфигурацию Turborepo.
  3. Быстрые сборки: Кэширование Turborepo проще в настройке и работает из коробки.
  4. Отсутствие vendor lock-in: Turborepo не оборачивает стандартные инструменты кастомными исполнителями.

Практическое применение

Шаги миграции

  1. Добавление turbo.json в корень:

    {
      "$schema": "https://turbo.build/schema.json",
      "tasks": {
        "build": {
          "dependsOn": ["^build"],
          "outputs": [".next/**", "!.next/cache/**", "dist/**"]
        },
        "test": {
          "outputs": ["coverage/**"],
          "cache": false
        },
        "lint": {
          "outputs": []
        },
        "lint:fix": {
          "cache": false,
          "outputs": []
        },
        "typecheck": {
          "outputs": []
        },
        "prettier": {
          "outputs": []
        },
        "dev": {
          "cache": false,
          "persistent": true
        }
      }
    }
    
  2. Обновление next.config.js:

    const path = require('path');
    const withBundleAnalyzer = require('@next/bundle-analyzer')({
      enabled: process.env.ANALYZE === 'true',
    });
    
    const nextConfig = {
      webpack(config) {
        config.module.rules.push({
          test: /\.svg$/i,
          issuer: /\.[jt]sx?$/,
          use: [{
            loader: '@svgr/webpack',
            options: {
              exportType: 'named',
              namedExport: 'ReactComponent',
              svgoConfig: {
                plugins: [{
                  name: 'preset-default',
                  params: {
                    overrides: {
                      removeViewBox: false,
                      cleanupIds: false,
                    },
                  },
                }],
              },
            },
          }],
        });
        return config;
      },
    };
    
    module.exports = withBundleAnalyzer(nextConfig);
    
  3. Исправление проблем с Jest:

    const nextJest = require('next/jest');
    const createJestConfig = nextJest({ dir: __dirname });
    
    module.exports = async () => {
      const config = await createJestConfig(customJestConfig)();
      config.transform = {
        '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': `${repoRoot}/mocks/svgTransformer.js`,
        ...config.transform,
      };
      config.moduleNameMapper = {
        ...config.moduleNameMapper,
        '^.+\\.(svg)$': `${repoRoot}/mocks/svgTransformer.js`,
      };
      return config;
    };
    

Заключение

Миграция с Nx на Turborepo была сложной, но оправданной. Мы получили более простую и прозрачную систему сборки, независимые деплои и ускоренный CI. Ключевые моменты: правильная настройка turbo.json, исправление проблем с SVG и адаптация Jest-конфигураций. Опыт нашей команды может быть полезен для других разработчиков, сталкивающихся с аналогичными вызовами.


Источник: https://dev.to/harsimran_singh_8d533462f/beyond-the-docs-the-hidden-challenges-of-nx-to-turborepo-migration-36b0