È uscito il Corso Java Completo
Torna al blog

Cos'è Vite e perché è diventato lo standard

Cos'è Vite e perché è così rapido: moduli ES nativi in sviluppo, build con Rollup in produzione, HMR, plugin e variabili d'ambiente con il prefisso VITE_.

Edoardo Midali

Edoardo Midali

Developer · Content Creator

9 min di lettura

Lanci npm run dev e il server è pronto in mezzo secondo, anche su un progetto con centinaia di file. Se vieni da qualche anno fa, dove quel comando significava andare a prendere un caffè, la differenza è difficile da ignorare. In questo articolo trovi cosa fa Vite in concreto, perché in sviluppo è così rapido, perché in produzione si comporta in modo completamente diverso — è il punto che confonde di più — e quando non sei tu a doverlo scegliere.

Cos'è Vite

Vite è lo strumento che fa girare il tuo progetto in sviluppo e lo prepara per la produzione: in sviluppo serve i file al browser senza impacchettarli, in produzione li impacchetta e ottimizza con Rollup.

Il nome è francese e significa "veloce": la rapidità non viene da micro-ottimizzazioni, ma dall'aver eliminato un intero passaggio. Il concetto generale di questi strumenti è in cos'è un bundler.

Il salto: in sviluppo non impacchetta

Gli strumenti precedenti, Webpack in testa, funzionavano così: all'avvio leggevano il file di ingresso, seguivano ogni import fino in fondo, trasformavano tutto e costruivano il pacchetto completo. Solo a quel punto potevi aprire il browser.

Su un progetto piccolo sono due secondi. Su uno vero, decine — e peggiora man mano che cresce, perché il lavoro all'avvio è proporzionale alla quantità di codice.

Vite parte dalla constatazione che i browser moderni sanno già caricare i moduli da soli:

<script type="module" src="/src/main.jsx"></script>

Il browser legge quel file, incontra gli import, e richiede i file collegati per conto suo. Vite si limita a essere il server che risponde a quelle richieste, trasformando ogni file nel momento in cui viene chiesto — JSX in JavaScript, TypeScript in JavaScript, e via.

Due conseguenze che si sentono subito:

  • L'avvio è quasi istantaneo, perché non c'è nessuna build iniziale: c'è solo un server che si mette in ascolto.
  • Il tempo di avvio non peggiora con la crescita del progetto. Vite trasforma solo i file che servono alla pagina che stai guardando. Le altre cinquanta schermate dell'applicazione, finché non le apri, non le tocca nessuno.

Un'eccezione: le dipendenze. Le librerie in node_modules non cambiano quasi mai e sono spesso composte da centinaia di file piccoli. Vite le pre-impacchetta una volta sola con esbuild e poi le serve dalla cache. Per questo il primo avvio dopo un'installazione richiede qualche secondo in più, e quelli successivi no.

L'HMR, e perché qui la differenza è ancora più netta

L'aggiornamento a caldo — Hot Module Replacement — sostituisce un modulo nella pagina aperta senza ricaricarla, mantenendo lo stato. Salvi il file, il componente si aggiorna, il modulo che stavi compilando resta pieno.

Non è una novità di Vite. Quello che cambia è quanto lavoro serve per farlo. Con un bundler classico, modificare un file significa ricalcolare una porzione del pacchetto: più il grafo è grosso, più il lavoro cresce, e su progetti grandi il ritardo tra salvataggio e aggiornamento diventa fastidioso.

Con Vite il pacchetto in sviluppo non esiste. Il file modificato viene ritrasformato da solo e mandato al browser, che sostituisce quel modulo e basta. Il tempo di aggiornamento resta costante anche su progetti grandi, perché dipende dal file che hai toccato, non da quanto è grande il progetto.

In produzione, invece, impacchetta davvero

Questa è la parte che genera più confusione, e vale la pena scriverla nel modo più netto possibile.

In sviluppo Vite non impacchetta. In produzione sì, con Rollup.

Se servire i moduli nativi funziona così bene, perché non farlo anche online? Perché i vincoli sono opposti. In sviluppo sei tu, in locale, con latenza zero: mille richieste piccole non costano niente. Online c'è una persona su una rete mobile lenta, e mille richieste in cascata — ognuna che ne scopre altre — sono un disastro per i tempi di caricamento.

Quindi vite build fa il lavoro classico: attraversa il grafo, elimina il codice non usato, minifica, spezza in pezzi sensati e scrive tutto in dist/.

vite devvite build
ImpacchettaNo, moduli serviti singolarmenteSì, con Rollup
TrasformazioneSu richiesta, file per fileTutto in anticipo
MinificazioneNo
Tree shakingNo
ObiettivoRiscontro immediatoFile più piccoli possibile

La conseguenza pratica è che i due percorsi sono diversi, e un problema può comparire solo in uno dei due. È l'origine del classico "in locale funziona, online no": magari un import con maiuscole sbagliate che il tuo filesystem perdona, o del codice che dipendeva da qualcosa rimosso dal tree shaking.

Per questo esiste vite preview, ed è il comando più sottovalutato dei tre:

npm run dev       # sviluppo, moduli nativi
npm run build     # produzione, output in dist/
npm run preview   # serve dist/ in locale: qui vedi cosa andrà online

Prova sempre con preview prima di pubblicare. Trenta secondi che evitano di scoprire un problema dopo il deploy.

Configurazione minima e plugin

Un progetto React completo sta in poche righe:

// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  server: { port: 3000 },
  resolve: {
    alias: { "@": "/src" },
  },
});

Quel file è tutta la configurazione che serve nella maggior parte dei casi, ed è la differenza più visibile rispetto ai webpack.config.js di qualche anno fa. TypeScript, CSS, importazione di immagini e JSON funzionano senza aggiungere nulla.

I plugin servono per le cose specifiche del framework. @vitejs/plugin-react per React, @vitejs/plugin-vue per Vue, @sveltejs/vite-plugin-svelte per Svelte. Poiché la build usa Rollup, è compatibile anche con gran parte dei plugin di Rollup.

Un avvertimento: aggiungi un plugin quando hai un problema che risolve, non perché sembra utile. Ogni plugin si infila nella trasformazione dei file, ed è il posto da cui arrivano gli errori più difficili da capire.

Le variabili d'ambiente e il prefisso VITE_

Questa sezione vale da sola l'articolo, perché qui si fanno due errori: uno che fa perdere tempo e uno che è un problema di sicurezza vero.

Vite legge i file .env e mette a disposizione le variabili su import.meta.env, ma espone al codice del browser soltanto quelle che iniziano con VITE_.

# .env
VITE_API_URL=https://api.miosito.it
VITE_NOME_APP=CodeGrind

DATABASE_URL=postgres://...        # NON esposta al browser
STRIPE_SECRET_KEY=sk_live_...      # NON esposta al browser
console.log(import.meta.env.VITE_API_URL); // funziona
console.log(import.meta.env.DATABASE_URL); // undefined

Primo errore, quello innocuo: aggiungi una variabile, la leggi nel codice e ottieni undefined. Nove volte su dieci manca il prefisso. La decima hai modificato il .env senza riavviare il server: quei file vengono letti all'avvio, non a ogni richiesta.

Secondo errore, quello grave: hai una chiave segreta che non funziona, provi ad aggiungere VITE_ davanti per "farla vedere al codice", e funziona. Sembra la soluzione.

Non lo è. Quel prefisso significa letteralmente "scrivi questo valore dentro i file che chiunque può scaricare". Il valore viene sostituito nel codice durante la build: finisce nel JavaScript pubblicato, visibile a chiunque apra gli strumenti di sviluppo del browser. Un .gitignore non ti protegge da nulla, perché il segreto non è nel repository: è online.

La regola è secca: se una chiave dà accesso a qualcosa che può costare soldi o esporre dati, non può stare in un'applicazione frontend. Né con Vite né con nessun altro strumento. Le chiamate che usano quella chiave vanno fatte da un server — un backend tuo, una funzione serverless, una route API. È esattamente la divisione descritta in frontend e backend, e il dettaglio completo sulla gestione dei segreti è in cosa sono le variabili d'ambiente.

Se una chiave ti finisce in un pacchetto pubblicato, non basta rimuoverla: va revocata e rigenerata. È già stata online.

Altre cose che fanno perdere ore

  • Percorsi assoluti che si rompono in produzione. Se pubblichi in una sottocartella va impostata l'opzione base. In locale funziona, online trovi una pagina bianca e richieste a 404.
  • Il CSS diventa enorme. Ogni file CSS importato da un modulo finisce nella build: se importi l'intero foglio di stile di una libreria di componenti per usarne tre, lo paghi tutto.
  • Cercare process.env e non trovarlo. In Vite è import.meta.env. È l'errore più frequente di chi arriva da Create React App o da Webpack.
  • Cancellare node_modules al primo comportamento strano. Spesso basta svuotare la cache delle dipendenze pre-impacchettate: npm run dev -- --force.

Quando non lo scegli tu

Punto onesto, e serve per non perdere tempo dietro a una decisione che non hai.

Se usi Next.js, Vite non c'entra niente. Next ha il proprio sistema di build, integrato con rendering lato server, rotte e caching: non lo sostituisci, sono due strade parallele. Nuxt, Astro, SvelteKit e Remix usano invece Vite sotto il cofano ma lo configurano loro — tu tocchi vite.config solo per casi particolari. Se stai decidendo, il confronto è in quale framework scegliere.

Vite lo scegli davvero quando parti da un'applicazione a pagina singola senza framework a livello superiore: un pannello di amministrazione in React, una dashboard Vue, un progetto Svelte. Lì npm create vite è la strada più corta che esista oggi.

E c'è il caso in cui non serve proprio: una pagina con un po' di HTML, CSS e un file JavaScript non ha bisogno di alcuno strumento di build. Ci metti un <script type="module"> e la apri. Aggiungere una toolchain a un sito di tre pagine significa aggiungere node_modules e un passaggio di build per risolvere problemi che non hai.

In sintesi

Vite fa due mestieri diversi con lo stesso nome, ed è la cosa da ricordare.

In sviluppo non impacchetta: serve i moduli ES nativamente al browser e trasforma i file su richiesta. Per questo l'avvio è quasi istantaneo e non peggiora quando il progetto cresce.

In produzione impacchetta con Rollup, con minificazione, tree shaking e code splitting. I due percorsi sono diversi: usa vite preview prima di pubblicare.

Le variabili d'ambiente hanno bisogno del prefisso VITE_ per essere visibili nel browser — e proprio per questo un segreto non va mai prefissato. Quel prefisso vuol dire "pubblicalo".

Non sempre è una tua scelta: con Next.js hai già il suo sistema, e su un sito piccolo puoi non usare alcuno strumento di build.

Per il quadro generale di cosa succede durante una build, vedi cos'è un bundler. Per il passo successivo, cioè mettere online il contenuto di dist/, vedi come fare il deploy di un sito e cos'è Vercel.