
Con Lerna in modalità manutenzione, anche se la sua gestione è recentemente passata a Nrwl, in illimity abbiamo avviato una fase di ricerca per capire quali fossero le migliori alternative e quali avremmo potuto adottare.
L'adozione di un nuovo strumento all'interno di un'azienda è un'operazione che incide su diversi aspetti.
Uno di questi è la produttività: è necessario che il nuovo strumento sia all'altezza delle esigenze e non crei nuovi problemi nel tempo.
Per scegliere il possibile nuovo strumento di gestione del monorepo, abbiamo eseguito alcuni benchmark.
Alcune operazioni vengono ripetute da ciascuno dei 40 sviluppatori front-end durante la giornata. Anche un piccolo miglioramento su una singola attività può fare la differenza nella quantità di lavoro svolto.
Di seguito confrontiamo Nx, Turborepo e Lerna, lo strumento che utilizziamo attualmente.
Misure originali in minuti decimali, su un unico asse dei tempi. Il trattino indica un risultato non riportato. La misura del cambio applicazione di Lerna non usa la cache.
Nel repository selezionato abbiamo 13 pacchetti TypeScript e 7 applicazioni. Ogni applicazione utilizza generalmente più di 6 pacchetti, che devono essere transpilati prima di poterla avviare. Analizzeremo le prestazioni di due task già presenti nel progetto: reset e install.
Attualmente, con Lerna, i due task svolgono le seguenti operazioni:
Reset: quando si passa da un'applicazione all'altra, oppure tra branch con funzionalità diverse, a volte è necessario eliminare le cartelle node_modules e le cartelle di build.
Install: per ciascuna applicazione, installa le dipendenze di terze parti necessarie e collega i pacchetti dichiarati come dipendenze nel package.json. Inoltre, devono essere installate le dipendenze richieste da ciascun pacchetto e, successivamente, deve essere transpilato il codice TypeScript.
Con Nx e Turborepo abbiamo deciso di sfruttare la funzionalità workspace di npm, per collegare i pacchetti locali in modo più dichiarativo rispetto alla soluzione attuale, e la funzionalità di pnpm che permette di scaricare le dipendenze di terze parti una sola volta e riutilizzarle in ogni progetto che le dichiara nel proprio package.json.
È necessario definire un nuovo task install, che richiami le funzioni specifiche di Nx o Turborepo e indichi allo strumento quale pipeline eseguire e per quale applicazione.
Per esempio, la pipeline install dichiarata nel file di configurazione nx.json richiama il task 'transpile' di ogni pacchetto locale, per definire l'ordine di esecuzione dei passaggi necessari ad avviare correttamente l'applicazione.
Il primo passaggio comprende l'eliminazione di tutte le cartelle node_modules e prosegue con l'esecuzione del task install, che per ciascuna applicazione installa le dipendenze necessarie e transpila i pacchetti utilizzati.
Abbiamo raccolto i dati prima disabilitando e poi abilitando il meccanismo di caching integrato di Nx e Turborepo.
| Task | Nx | Turborepo | Lerna |
|---|---|---|---|
| Reset | 2,41 | 2,15 · Più veloce | 3,36 |
| Installazione | 1,21 · Più veloce | 1,42 | 1,80 |
| Installazione · cache, prima esecuzione | 1,18 · Più veloce | 1,24 | — |
| Installazione · cache, seconda esecuzione | 0,17 · Più veloce | 0,28 | — |
| Installazione · cambio applicazione | 0,14 · Più veloce | 0,29 | 1,23 |
Misure originali in minuti decimali. I valori evidenziati sono i più veloci per ogni task. Il trattino indica un risultato non riportato. La misura del cambio applicazione di Lerna non usa la cache.
I dati mostrano che Nx è più lento di Turborepo nell'esecuzione del task reset, ma è leggermente più veloce negli altri task. Purtroppo Lerna non dispone di un meccanismo di caching: quando viene eseguito il comando install, ogni pacchetto viene transpilato nuovamente.
In un ambiente monorepo, uno sviluppatore può dover passare da un'applicazione all'altra per avviare un nuovo processo o risolvere un bug. Questa metrica mostra quanto tempo si può risparmiare migrando a Nx. Con Nx e Turborepo vengono transpilati soltanto i pacchetti che non lo sono già stati.
Abbiamo considerato anche altri aspetti per capire quale soluzione potesse essere la migliore per il nostro team. Di seguito mostriamo una tabella comparativa di alcune funzionalità offerte dai tre strumenti.
| Funzionalità | Nx | Turborepo | Lerna |
|---|---|---|---|
| Esecuzione distribuita dei task | Inclusa | Non inclusa | Non inclusa |
| Visualizzazione del grafo delle dipendenze | Inclusa | Inclusa | Non inclusa |
| Rilevamento di progetti e pacchetti interessati | Inclusa | Inclusa | Inclusa |
| Vincoli e visibilità dei progetti | Inclusa | Non inclusa | Non inclusa |
| Cache distribuita dei risultati | Inclusa | Inclusa | Non inclusa |
| Cache locale dei risultati | Inclusa | Inclusa | Non inclusa |
| Ottimizzazioni dei cache hit (Windows) | Inclusa | Non inclusa | Non inclusa |
Confronto originale del 2022. Sono indicate soltanto le funzionalità integrate e disponibili senza configurazioni aggiuntive.
In attesa di capire come evolverà Lerna, Nx sembra essere la soluzione giusta per le nostre esigenze. La velocità di orchestrazione dei task, le ottimizzazioni della cache, la sua diffusione e tutte le funzionalità disponibili lo rendono uno standard di fatto nella gestione dei repository monorepo.
Articoli correlati: