Traspilazione è la conversione del codice sorgente da un linguaggio di programmazione a un altro allo stesso livello di astrazione. A differenza della compilazione in codice macchina, la traspilazione traduce codice tra linguaggi di alto livello: TypeScript in JavaScript, Kotlin in Java, Dart in JavaScript. Secondo Babel Documentation, Babel è il traspilatore più popolare con oltre 35 milioni di download settimanali e supporto per centinaia di plugin.
Punti chiave
Traspilazione (compilazione source-to-source) è il processo di traduzione di un programma da un linguaggio di programmazione a un altro mantenendo lo stesso livello di astrazione. Un traspilatore prende il codice sorgente nel linguaggio A e genera codice equivalente nel linguaggio B che può essere eseguito nell'ambiente di destinazione. Esempi tipici: TypeScript in JavaScript, SASS in CSS, Haxe in più linguaggi di destinazione.
La traspilazione differisce dalla compilazione in quanto il codice di output rimane ad un alto livello e può essere letto da umani (sebbene non sia destinato a questo scopo). Un compilatore (GCC, LLVM, javac) traduce codice in codice macchina o bytecode — un formato illeggibile. Un traspilatore genera codice che può essere ulteriormente compilato o minimizzato.
Perché serve la traspilazione. Il motivo principale è la compatibilità. Gli sviluppatori vogliono usare linguaggi moderni (TypeScript con tipi, Kotlin con null safety), ma la piattaforma di destinazione supporta solo JavaScript o Java. La traspilazione consente di scrivere in un linguaggio moderno mentre si distribuisce codice comprensibile per l'ambiente di destinazione.
| Traspilatore | Sorgente → Destinazione | Applicazione |
|---|---|---|
| Babel | ES6+/TypeScript → ES5 | Sviluppo web, React, Vue |
| tsc (TypeScript Compiler) | TypeScript → JavaScript | Qualsiasi applicazione TypeScript |
| kotlinc-js | Kotlin → JavaScript | Kotlin/JS, React Kotlin Wrappers |
| dart2js | Dart → JavaScript | Flutter Web, AngularDart |
| SWC | TypeScript/JS → ES5 | Next.js, bundling basato su Rust |
Livello di astrazione è la differenza principale. Un traspilatore traduce codice tra linguaggi dello stesso livello (alto livello → alto livello). Un compilatore traduce da alto livello a basso livello (codice macchina, bytecode). LLVM IR è una rappresentazione intermedia ma è comunque di livello inferiore rispetto al C++ o Rust originale.
Leggibilità del risultato è la seconda differenza. Il risultato della traspilazione (JavaScript da TypeScript) è leggibile e può essere debugato nel browser. Il risultato della compilazione (codice macchina da C++) non è destinato alla lettura — la sua analisi richiede un disassemblatore. Le source map aiutano a eseguire il debug del codice traspilato collegandolo al codice sorgente originale.
Nelle pipeline CI/CD, la traspilazione viene eseguita nella fase di build. Per i progetti TypeScript, tsc o Babel vengono eseguiti in un container Docker, generano JavaScript e source map, che vengono poi minimizzati e distribuiti su un server o nell'app store. È importante configurare la memorizzazione nella cache dei risultati di traspilazione — tsc --incremental salva il grafo delle dipendenze tra le esecuzioni, riducendo il tempo di build del 30–50%.
Per i progetti mobili (React Native), la traspilazione tramite Metro Bundler viene eseguita sul server CI ad ogni pubblicazione. Le directory cache (tmp/metro-cache) e le build parallele tramite --workers accelerano il processo. GitHub Actions e GitLab CI supportano la memorizzazione nella cache delle directory node_modules e .cache tra le esecuzioni, il che è fondamentale per ridurre i tempi della pipeline.
Velocità di esecuzione differisce anch'essa. La compilazione in codice macchina offre le massime prestazioni. La traspilazione preserva l'overhead del livello di astrazione: il JavaScript da TypeScript viene eseguito alla stessa velocità del JavaScript normale. Le ottimizzazioni (TypeScript —strict) funzionano in fase di analisi, non in fase di esecuzione.
Scenario 1: TypeScript → JavaScript — lo scenario più comune. Lo sviluppatore scrive TypeScript con tipi, il compilatore tsc o Babel rimuove le annotazioni di tipo e genera JavaScript puro. Tutti i progetti Angular e la maggior parte dei progetti React (2026) utilizzano la traspilazione TypeScript. Secondo State of JS 2025, il 79% degli sviluppatori intervistati utilizza TypeScript nei propri progetti principali.
Scenario 2: Kotlin → JavaScript — utilizzato in Kotlin/JS per lo sviluppo full-stack. Il codice Kotlin viene compilato in JavaScript tramite il Compilatore Kotlin con IR (Intermediate Representation). Kotlin/JS supporta dichiarazioni tipizzate TypeScript (.d.ts) per l'integrazione con librerie JS esterne. JetBrains utilizza Kotlin/JS nei propri prodotti per le interfacce web.
Scenario 3: SASS/SCSS → CSS — traspilazione di preprocessori CSS. Dart Sass (l'implementazione raccomandata) traspila .scss in .css, espandendo mixin, variabili, regole annidate e funzioni. Questa non è compilazione (CSS rimane CSS), ma traspilazione con estensione sintattica.
| Parametro | Traspilazione | Compilazione | Interpretazione |
|---|---|---|---|
| Input → Output | Alto livello → Alto livello | Alto livello → Codice macchina | Codice → Esecuzione immediata |
| Esempio | TypeScript → JavaScript | C++ → ARM/x86 | Python → runtime CPython |
| Codice output leggibile | Sì | No | N/D |
| Prestazioni | Come il linguaggio target | Massime | Inferiori alla compilazione |
| Richiede runtime | No (codice target puro) | No | Sì |
Babel è il traspilatore JavaScript più popolare, che converte codice ES6+/ESNext in JavaScript compatibile ES5. Babel funziona tramite un sistema di plugin e preset: ogni plugin è responsabile di una trasformazione (arrow function, async/await, optional chaining). @babel/preset-env determina automaticamente i plugin necessari in base ai browser target (browserslist).
L'architettura di Babel consiste in tre fasi: parsing → trasformazione → generazione. Il parser (Babylon/@babel/parser) converte il codice sorgente in un AST (Abstract Syntax Tree). I trasformatori (plugin) modificano l'AST. Il generatore (@babel/generator) produce il codice di output dall'AST modificato.
// Codice ES6+ originale
const greet = (name = "World") => {
return `Hello, ${name}!`;
};
class User {
constructor(name) {
this.name = name;
}
}
const data = { user: { address: { city: "Moscow" } } };
const city = data?.user?.address?.city;// Dopo Babel (target: > 0.25%, not dead)
"use strict";
var greet = function (name) {
if (name === void 0) { name = "World"; }
return "Hello, " + name + "!";
};
var User = function (name) {
this.name = name;
};
var data = { user: { address: { city: "Moscow" } } };
var city = data != null
? data.user != null
? data.user.address != null
? data.user.address.city
: void 0
: void 0
: void 0;Babel ha trasformato: la arrow function in una function expression, il parametro predefinito (name = "World") in un controllo void 0, la template string in concatenazione, la classe in una funzione costruttore e l'optional chaining (?.) in una catena di operatori ternari. const è stato sostituito con var per la compatibilità ES5.
TypeScript è un linguaggio fortemente tipizzato che viene traspilato in JavaScript. Il compilatore tsc (TypeScript Compiler) esegue due compiti: type checking e traspilazione (emit). È importante capire: il type checking e la traspilazione sono fasi indipendenti. È possibile eseguire la traspilazione senza type checking (--noEmitOnError false) o il type checking senza generazione di codice (--noEmit true).
Traspilazione TypeScript rimuove tutte le annotazioni di tipo, interfacce, type alias e parametri generici — non esistono in JavaScript. Gli Enum vengono convertiti in oggetti, i decoratori in chiamate di funzione, async/await in generatori (se target è inferiore a ES2017). tsconfig.json controlla target (versione JavaScript), module (sistema di moduli), strict (rigore del type checking) e outDir (cartella di output).
{
"compilerOptions": {
"target": "es2015",
"module": "esnext",
"lib": ["es2015", "dom"],
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
"esModuleInterop": true,
"sourceMap": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}target: "es2015" istruisce tsc a generare JavaScript con sintassi ES6 (arrow function, classi, let/const). module: "esnext" preserva i moduli ES (import/export) per il successivo Tree Shaking in Webpack. strict: true abilita tutti i controlli di tipo (strictNullChecks, noImplicitAny, strictFunctionTypes). declaration: true genera file .d.ts per i consumatori TypeScript della libreria.
React Native utilizza Babel e Metro per traspilare JavaScript/TypeScript in codice eseguibile da JavaScriptCore (iOS) o Hermes (Android). I plugin Babel aggiungono trasformazione JSX, annotazioni Flow/TypeScript e ottimizzazioni specifiche di React Native. Metro Bundler inoltre raggruppa i moduli ed esegue Hot Module Replacement per lo sviluppo.
Flutter utilizza la traspilazione Dart. Per Flutter Web, dart2js traspila Dart in JavaScript ottimizzato. Per Flutter Mobile, dart2native compila Dart in codice ARM nativo. Flutter supporta anche Dart DevCompiler (dartdevc) per lo sviluppo — traspila Dart in JavaScript più velocemente ma con minore ottimizzazione.
// babel.config.js — Traspilazione React Native
module.exports = {
presets: [
["module:metro-react-native-babel-preset"],
],
plugins: [
["module-resolver", {
root: ["."],
alias: {
"@": "./src",
"@components": "./src/components",
},
}],
"react-native-reanimated/plugin",
],
env: {
production: {
plugins: ["transform-remove-console"],
},
},
};metro-react-native-babel-preset include tutti i plugin necessari per React Native: JSX, Flow/TypeScript, il sistema di moduli Metro, async/await, class properties e decoratori. Il plugin module-resolver aggiunge alias per import brevi (@/components/Button invece di ../../components/Button). In modalità produzione, transform-remove-console rimuove tutti i console.log dal codice.
Domande frequenti
Traspilazione traduce codice da un linguaggio a un altro allo stesso livello (esempio: TypeScript → JavaScript). Compilazione traduce da alto livello a basso livello (C++ → codice macchina). Il risultato della traspilazione è leggibile, quello della compilazione no.
React Native richiede la traspilazione per impostazione predefinita — Metro Bundler utilizza Babel per convertire JSX, TypeScript e JavaScript moderno in codice compatibile con JavaScriptCore e Hermes. Senza Babel, React Native non può eseguire la sintassi JSX dei componenti.
Sì: Babel con @babel/preset-typescript e SWC supportano la traspilazione TypeScript. È più veloce di tsc, ma Babel non esegue il type checking — rimuove solo le annotazioni di tipo. Per il type checking, è necessario eseguire tsc --noEmit separatamente o tramite fork-ts-checker-webpack-plugin.
Source map sono file che collegano il codice traspilato al codice sorgente originale. Consentono di eseguire il debug di TypeScript nel browser: i punti di interruzione vengono impostati nei file .ts, gli stack trace mostrano righe .ts invece di .js. Senza source map, il debug del codice traspilato è praticamente impossibile.
La traspilazione stessa non influisce sulle prestazioni dell'applicazione — il codice di output viene eseguito alla stessa velocità del codice scritto nativamente nel linguaggio target. L'overhead si verifica solo se il traspilatore genera codice non ottimale (ad esempio, Babel può creare polyfill ingombranti per i metodi degli array).
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche