Configurazione funzionante per monorepo pnpm con TypeScript, Vite e Rollup
Creo un monorepo usando i workspace di pnpm e ho problemi a farlo funzionare. Usa TypeScript, Vite sui frontend, Rollup nei microservizi backend.
Ecco l'impostazione:
package.json <== all dependencies reside here
tsconfig.json
pnpm-workspaces.yaml
- commonlib/
package.json, tsconfig.json, rollup.config.js
src/
...interfaces, types etc---
- serverlib/
package.json, tsconfig.json, rollup.config.js
src/
...modules for common server/microservice funtionality---
- weblib/
package.json, tsconfig.json, vite.config.js
src/
...react etc components & functions---
- servers/
srv-gateway/
package.json, tsconfig.json, rollup.config.js
src/
...server code...
ms-xxx/ <== Multiple REST microservices
package.json, tsconfig.json, rollup.config.js
src/
...microservice code...
- webapps/
app/
package.json, tsconfig.json, vite.config.js
src/
...main application code---
admin/
package.json, tsconfig.json, vite.config.js
src/
...application code---
app-2/ <== Other webapps / micro frontends
...
La mia/e richiesta/e:
- Mantengo tutte le dipendenze dei pacchetti nel file package.json principale
- Voglio accedere ai miei moduli come @myapp/commonlib, @myapp/weblib, ...
- Non ho intenzione di pubblicare nessuno di questi su npmjs (non sono generici - quindi non voglio usare semver per le librerie)
- Voglio le versioni di dipendenze più recenti (le aggiorno quotidianamente). Voglio anche più tipi per ciascuna, cjs, es, esm ecc. qui potrebbe essere dove ho sbagliato.
I miei problemi:
- Sono perso nelle definizioni di package.json, tsconfig.json, rollup.config.json e vite.config.json - è diventato troppo complesso.
- Devo compilare/traspilarle la *lib e versionarle o basta includerle in qualche modo?
- Includere come? Come dipendenze (@myapp/...)? Usando "path" e "references" nei server/webapp reali? Se sì, devo fare vite/rollup di queste *lib?
- Ad esempio, in weblib, lo compilo escludendo tutti i pacchetti esterni (vite.config.ts -> rollupOptions -> external) ma ora non riesco a far funzionare l'app web (schermo vuoto).
Prima avevo un sistema funzionante, in cui definivo @myapp/uilib, @myapp/graphlib ecc. e usavo "path" e "references". Ma man mano che aumentavano di numero, volevo combinarli in un'unica libreria. È qui che ho perso la traccia. Ho fatto troppi cambiamenti per tornare a uno stato git precedente. La colpa è di molti tutorial contrastanti che ho visto e di ChatGPT, e ovviamente principalmente mia :/
Apparentemente lo faccio tutto sbagliato, ora voglio imparare il modo corretto.
Grazie in anticipo per il tuo aiuto.
Risposta n. 1
Dopo una lunga lista di prove, difficoltà e test delle prestazioni, ho deciso per questi:
- Avere dipendenze alla radice di un monorepo è una cattiva idea. Ogni volta che arrivavo alla fase di creazione di Docker, dovevo spostare le dipendenze nei rispettivi pacchetti. Il gestore di pacchetti (pnpm) le mantiene già al livello più alto e le collega dai singoli pacchetti.
- Poiché sto lavorando con i microservizi, ognuno è diventato piccolo dopo il refactoring. Quindi, la fase di packaging è diventata inutile, e ho abbandonato rollup sul lato server e mi sono rivolto a esbuild. Fornisce bundle esm (ES2020 per ora) ottimizzati e rispetta i "references" in tsconfig.json. (tsup non lo fa - ancora, l'ho provato e poi rimosso)
- A seguito del punto precedente, ho spostato i file statici fuori dalla generazione del bundle (avevo file dati statici/json che servivo con express-static). Ho spostato i dati in un'installazione static.mydomain.com, quindi mi sono liberato dei lunghi processi di copia durante le build.
- Per ora mantengo le configurazioni vite/rollup nelle applicazioni frontend React, funzionano bene - tranne per il problema con Vite in modalità sviluppo che parte molto lentamente.
- In tutte le librerie comuni, frontend e server, ho usato di nuovo i bundle di esbuild (solo ES2020).
- Ho anche spostato tutto il frontend e i server finali in "apps" e ho spostato le librerie nelle directory "libs".
- Continuavo a usare la struttura multi-livello di tsconfig.json.
Questa è stata una lunga lezione per me nel mio primo monorepo. Cercherò di aggiornare questo post con la mia struttura.