{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"]
},
"lint": {
"outputs": []
},
"dev": {
"cache": false,
"persistent": true
}
}
}Salutare. M-am lovit recent de o problemă clasică la un proiect de e-commerce cu vreo 15k utilizatori activi, unde a trebuit să ridicăm 3 aplicații Next.js: magazinul principal, un dashboard de admin și un flux separat de checkout. Toate trebuiau să împartă cam 80% din componentele de UI și logica de business.
Am testat pe rând simple workspaces (pnpm), Nx și Turborepo. Am pierdut vreo două săptămâni doar cu configurările și pipeline-urile de CI/CD. Vreau să vă zic direct ce a funcționat, ce a crăpat și unde am dat cu capul de pragul de sus, ca să nu faceți aceleași greșeli.
De ce simple workspaces (pnpm/npm) devin rapid un chin
Am pornit la drum super optimist. Am zis că nu am nevoie de tool-uri extra, așa că am configurat pnpm workspaces. Structura era simplă: un folder apps pentru cele trei aplicații Next.js și un folder packages/ui pentru componentele comune.
La început, totul a mers brici. Symlink-urile locale funcționează nativ, Next.js le vede imediat prin transpilePackages. Problema a apărut la deployment în CI.
Fără un tool inteligent de orchestrare, CI-ul rula next build pe toate cele trei aplicații la fiecare commit, chiar dacă eu modificasem doar o linie de text în footer-ul de la checkout. Am sărit rapid de la un build time de 3 minute la peste 14 minute. În plus, gestionarea task-urilor în paralel (de genul "pornește dev server-ul pentru toate aplicațiile") devenise un script de bash horror plin de concurrently și procese orfane care îmi blocau porturile.
Merge excelent pentru proiecte mici unde lucrezi singur, dar devine complet nesustenabil când ai mai mult de doi developeri pe proiect.
Nx: Putere imensă, dar overhead de te doare capul
Am zis să trec la Nx, că doar e standardul în industrie pentru monorepos mari. Am rulat generatorul lor, am configurat totul și, într-adevăr, dependency graph-ul lor este o operă de artă. Știe exact ce fișier afectează ce aplicație.
Dar am dat rapid de un trade-off major: complexitatea.
Pentru 3 aplicații Next.js și o librărie de UI, Nx mi s-a părut ca și cum aș trage cu tunul în vrăbii. Ne-am blocat în configurări absurde de TypeScript, generatoare care ne rescriau fișierele de configurare și probleme de compatibilitate între versiunile de Webpack impuse de Nx și cele folosite intern de Next.js. Dacă nu ai un om dedicat pe DevOps/Platform în echipă care să se ocupe doar de mentenanța structurii Nx, pur și simplu nu merită efortul cognitiv.
Turborepo: Sweet spot-ul pentru ecosistemul Next.js
Până la urmă, am șters tot și am configurat Turborepo. Fiind cumpărat de Vercel, integrarea cu Next.js este aproape organică.
Configurarea se face printr-un singur fișier turbo.json în root. Am definit acolo pipeline-ul: ce task-uri depind de altele și ce anume trebuie cache-uit. De exemplu, build-ul aplicațiilor depinde de build-ul pachetelor de UI.
Am economisit cam 45% la build time în CI încă din prima zi datorită caching-ului local. Când am activat și Remote Caching pe Vercel, build-urile care nu aveau modificări pe codul sursă au scăzut la sub 10 secunde, pentru că descărcau direct artifact-ul gata compilat.
Care e șmecheria cu componentele comune?
Ca să funcționeze totul fără bătăi de cap cu bundlerele, în packages/ui nu facem compile la nimic. Exportăm direct TypeScript / JSX brut.
În fiecare aplicație Next.js, în next.config.js, adăugăm:
transpilePackages: ["@repo/ui"]
Astfel, Next.js-ul din fiecare aplicație se ocupă de compilarea componentelor comune exact ca și cum ar fi scrise local. Primești hot reloading instantaneu când modifici o componentă din packages/ui și lucrezi în oricare din cele 3 aplicații.
Trade-off-ul sincer: Turborepo este excelent dacă rămâi în ecosistemul Next.js/React și livrezi totul în interiorul acelui monorepo. Dacă vrei să publici componentele separat pe npm pentru alte echipe din exterior, structura asta devine rigidă și va trebui să adaugi manual TSUP sau Rollup ca să faci build separat la pachete.
Voi ce folosiți pentru monorepo-uri cu Next.js? Ați rămas pe pnpm workspaces sau ați trecut la Turborepo?