{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"lint": {
"outputs": []
},
"dev": {
"cache": false,
"persistent": true
}
}
}Am avut de pus pe picioare un proiect cu 3 aplicații Next.js – un dashboard de admin, un portal B2B pentru clienți și site-ul public de prezentare. Toate trebuiau să împartă cam 80% din UI (butoane, formulare, tabele, plus layout-ul de brand). Am vrut să scap repede, așa că am început cu pnpm workspaces clasic, dar m-am blocat rapid în detalii de configurare.
Iată ce am învățat din toată experiența asta și cum am ajuns la un setup stabil.
De ce pnpm workspaces simplu devine rapid un coșmar
La început zici că e simplu. Faci un folder packages/ui, pui componentele acolo și le imporți în aplicații. Dar când ai 3 aplicații mari și o echipă de 4 oameni, apar problemele de build și de cache.
Fără un manager de monorepo dedicat, când modifici o singură linie în packages/ui, nu ai un mod inteligent de a rula build-ul doar pentru ce s-a schimbat. Nu ai cache local sau remote. La fiecare push pe GitHub, CI-ul reconstruia absolut tot de la zero. Am pățit să stau și 15 minute la un build pe care acum, cu cache inteligent, îl rezolvăm în mai puțin de 3 minute.
Nx vs Turborepo: Monstrul vs Pragmaticul
După ce mi-am pierdut răbdarea cu workspaces simple, am testat ambele variante mari din ecosistem.
Nx este o uzină incredibil de puternică. Îți generează grafice de dependențe, are plugin-uri pentru aproape orice și știe să ruleze doar ce s-a modificat cu o precizie chirurgicală. Dar trade-off-ul e masiv: curba de învățare e abruptă. Fișierele lor de configurare adaugă un strat de complexitate care mie mi s-a părut prea mult pentru Next.js. Dacă nu ai un om dedicat pe DevOps în echipă, Nx te poate copleși repede.
Turborepo (luat de cei de la Vercel) s-a potrivit la fix. Este gândit nativ pentru Next.js și configurarea e aproape instananee. Practic, definești într-un singur fișier turbo.json ce comenzi depind de altele și gata. Am economisit cam 30% la build time pe CI încă din prima zi doar din configurarea cache-ului lor gratuit pe Vercel.
Capcana celor „80% componente partajate”
Aici e o problemă de arhitectură pe care mulți o ignoră. Când partajezi atât de mult cod, riști să creezi un monolit strâns cuplat (tightly coupled) ascuns sub masca unui monorepo. Dacă modifici o culoare în butonul de bază din packages/ui, Turborepo va invalida cache-ul pentru toate cele 3 aplicații Next.js. Asta înseamnă că tot le vei reconstrui pe toate trei destul de des.
Sfatul meu după ce am dat cu capul de pragul de sus: nu pune totul într-un singur pachet gigant numit ui. Sparge-l în:
packages/ui-core: componente atomice (butoane, inputuri, modaluri, chestii fără business logic).packages/ui-features: componente mai mari care conțin logică (de exemplu, un tabel de useri cu fetch inclus).packages/utils: funcții helper, validări de scheme (Zod) și hooks.
Astfel, dacă modifici un tabel folosit doar în Admin, portalul de clienți și site-ul public își vor lua cache complet la următorul build, fără să piardă timp prețios pe CI.
Cum aveți structurate monorepo-urile mari în producție? A rămas cineva pe simple workspaces fără tool-uri de build și e fericit cu asta la mai mult de 2 aplicații?