El ecosistema de build para TypeScript
El compilador oficial de TypeScript (tsc) realiza dos tareas: verificación de tipos y transpilación a JavaScript. Las herramientas modernas de build separan estas responsabilidades para ganar velocidad: transpilan TypeScript a JavaScript sin verificar tipos, delegando la comprobación al editor o a tsc --noEmit.

# Transpilación + verificación (lento)
tsc
# Solo verificación de tipos (rápido para CI)
tsc --noEmit
# Solo transpilación (muy rápido con herramientas modernas)
esbuild archivo.ts --outfile=archivo.js
La separación entre transpilación y verificación de tipos es el principio fundamental de las herramientas modernas. Transpilan eliminando las anotaciones de tipo sin analizarlas, lo que permite velocidades ordenes de magnitud superiores a
tsc.
Esta separación implica que algunas funcionalidades que dependen de la verificación de tipos no están disponibles en transpiladores rápidos:
const enum(se trata comoenumregular)namespacecon fusión de declaraciones- Paths de
tsconfig.json(requieren plugin adicional) emitDecoratorMetadata(requiere compilación completa)
esbuild: transpilación ultrarapida
esbuild es un bundler y transpilador escrito en Go que procesa TypeScript eliminando las anotaciones de tipo sin ejecutar verificación. Es la base sobre la que Vite construye su servidor de desarrollo.
npm install -D esbuild
Transpilación básica
# Archivo individual
npx esbuild archivo.ts --outfile=archivo.js
# Directorio completo
npx esbuild src/**/*.ts --outdir=dist
# Con formato de módulo
npx esbuild archivo.ts --outfile=archivo.js --format=esm
# Minificado para producción
npx esbuild archivo.ts --bundle --minify --outfile=dist/app.js
API programatica
// archivo: build.ts
import * as esbuild from "esbuild"
async function construir() {
const resultado = await esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
outdir: "dist",
format: "esm",
platform: "node",
target: "es2022",
minify: true,
sourcemap: true
})
if (resultado.errors.length > 0) {
console.error("Errores:", resultado.errors)
} else {
console.log("Build completado")
}
}
construir()
Watch mode para desarrollo
// archivo: dev.ts
import * as esbuild from "esbuild"
async function iniciarDesarrollo() {
const contexto = await esbuild.context({
entryPoints: ["src/index.ts"],
bundle: true,
outdir: "dist",
format: "esm",
platform: "node",
sourcemap: true
})
await contexto.watch()
console.log("Observando cambios...")
}
iniciarDesarrollo()
esbuild procesa TypeScript mediante type stripping: elimina las anotaciones de tipo y convierte la sintaxis de TypeScript a JavaScript válido sin analizar la semántica de los tipos:
// Entrada TypeScript
interface Usuario {
nombre: string
edad: number
}
function saludar(usuario: Usuario): string {
return `Hola, ${usuario.nombre}`
}
const resultado: string = saludar({ nombre: "Ana", edad: 28 })
// Salida JavaScript (type stripping)
function saludar(usuario) {
return `Hola, ${usuario.nombre}`
}
const resultado = saludar({ nombre: "Ana", edad: 28 })
Vite: servidor de desarrollo y build
Vite es una herramienta de desarrollo que combina un servidor de desarrollo ultrarapido basado en ESM nativo del navegador con un sistema de build basado en Rollup (y esbuild para la transpilación).
npm create vite@latest mi-proyecto -- --template vanilla-ts
cd mi-proyecto
npm install
npm run dev
Estructura de proyecto Vite con TypeScript
mi-proyecto/
src/
main.ts
tipos.ts
utilidades.ts
index.html
tsconfig.json
vite.config.ts
package.json
Configuración de Vite
// archivo: vite.config.ts
import { defineConfig } from "vite"
export default defineConfig({
build: {
target: "es2022",
outDir: "dist",
sourcemap: true,
lib: {
entry: "src/main.ts",
formats: ["es", "cjs"],
fileName: (format) => `main.${format === "es" ? "mjs" : "cjs"}`
}
},
server: {
port: 3000,
open: true
}
})
Como funciona Vite en desarrollo
En desarrollo, Vite sirve los módulos TypeScript directamente al navegador. Cuando el navegador solicita un archivo .ts, Vite lo transpila al vuelo con esbuild y lo sirve como JavaScript:
// archivo: src/main.ts
import { formatearFecha } from "./utilidades"
interface Evento {
titulo: string
fecha: Date
ubicacion: string
}
function crearEvento(titulo: string, fecha: Date, ubicacion: string): Evento {
return { titulo, fecha, ubicacion }
}
function mostrarEvento(evento: Evento): string {
return `${evento.titulo} - ${formatearFecha(evento.fecha)} en ${evento.ubicacion}`
}
const evento = crearEvento("Conferencia TypeScript", new Date(), "Madrid")
console.log(mostrarEvento(evento))
// archivo: src/utilidades.ts
export function formatearFecha(fecha: Date): string {
return fecha.toLocaleDateString("es-ES", {
year: "numeric",
month: "long",
day: "numeric"
})
}
export function capitalizarPrimeraLetra(texto: string): string {
return texto.charAt(0).toUpperCase() + texto.slice(1)
}
Build para producción
# Build de producción
npm run build
# Preview del build
npm run preview
El build de producción usa Rollup para generar bundles optimizados con tree-shaking, code splitting y minificación.
Vite para bibliotecas
Vite puede configurarse para empaquetar bibliotecas TypeScript que se publican en npm:
// archivo: vite.config.ts
import { defineConfig } from "vite"
import { resolve } from "path"
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, "src/index.ts"),
name: "MiBiblioteca",
formats: ["es", "cjs"],
fileName: (format) => `index.${format === "es" ? "mjs" : "cjs"}`
},
rollupOptions: {
external: ["zod"],
output: {
globals: {
zod: "Zod"
}
}
}
}
})
SWC: transpilación basada en Rust
SWC (Speedy Web Compiler) es un transpilador escrito en Rust que compite con esbuild en velocidad. Es la base de Next.js y otras herramientas del ecosistema:
npm install -D @swc/core @swc/cli
# Transpilar archivo
npx swc src/index.ts -o dist/index.js
# Transpilar directorio
npx swc src -d dist
# Con sourcemaps
npx swc src -d dist --source-maps
Configuración de SWC
{
"$schema": "https://swc.rs/schema.json",
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true,
"dynamicImport": true
},
"target": "es2022",
"loose": false
},
"module": {
"type": "es6"
},
"minify": false,
"sourceMaps": true
}
SWC se integra con otros frameworks y herramientas como plugin de transpilación:
// archivo: webpack.config.ts (ejemplo de integración)
import type { Configuration } from "webpack"
const config: Configuration = {
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: "swc-loader",
options: {
jsc: {
parser: {
syntax: "typescript"
},
target: "es2022"
}
}
}
}
]
}
}
export default config
tsx: reemplazo moderno de ts-node
tsx es un ejecutor de TypeScript para Node.js que usa esbuild internamente. Es la alternativa moderna a ts-node, con configuración mínima y soporte completo para ESM:
npm install -D tsx
# Ejecutar archivo TypeScript
npx tsx archivo.ts
# Watch mode
npx tsx watch archivo.ts
# Usar como loader de Node.js
node --import tsx archivo.ts
Comparación tsx vs ts-node
// archivo: servidor.ts
import http from "node:http"
interface Respuesta {
estado: string
timestamp: number
}
const servidor = http.createServer((req, res) => {
const respuesta: Respuesta = {
estado: "activo",
timestamp: Date.now()
}
res.writeHead(200, { "Content-Type": "application/json" })
res.end(JSON.stringify(respuesta))
})
servidor.listen(3000, () => {
console.log("Servidor en http://localhost:3000")
})
# Con ts-node (requiere configuración, puede fallar con ESM)
npx ts-node servidor.ts
# Con tsx (funciona directamente)
npx tsx servidor.ts
# Con tsx en watch mode
npx tsx watch servidor.ts
tsx no requiere configuración adicional: detecta automáticamente si el proyecto usa ESM o CommonJS y ajusta el comportamiento. Esto elimina los problemas habituales de ts-node con "type": "module" en package.json.
Comparativa de herramientas
| Herramienta | Lenguaje | Verificación de tipos | Velocidad transpilación | Bundling | Uso principal | |---|---|---|---|---|---| | tsc | TypeScript | Si | Lenta | No | Verificación + build oficial | | esbuild | Go | No | Muy rápida | Si | Transpilación y bundling | | SWC | Rust | No | Muy rápida | Parcial | Plugin de transpilación | | Vite | JS (usa esbuild) | No | Rápida | Si (Rollup) | Dev server + build web | | tsx | JS (usa esbuild) | No | Rápida | No | Ejecutar .ts en Node.js | | Bun | Zig | No | Muy rápida | Si | Runtime completo |
Cuando usar cada herramienta
// Verificacion de tipos: siempre tsc
// package.json
{
"scripts": {
"typecheck": "tsc --noEmit",
"build": "vite build",
"dev": "vite",
"start": "tsx src/index.ts",
"test": "vitest"
}
}
- Proyectos web (frontend): Vite como dev server y build tool
- Bibliotecas npm: tsc para declaraciones
.d.ts+ esbuild o Vite lib mode para el bundle - Scripts y servidores Node.js: tsx para desarrollo, esbuild para bundle de producción
- CI/CD:
tsc --noEmitpara verificación de tipos + herramienta rápida para build - Monorepos: SWC o esbuild como plugin de transpilación en el bundler del monorepo
La estrategia recomendada para proyectos modernos es usar
tsc --noEmitexclusivamente para verificación de tipos (en CI y como script de pre-commit) y una herramienta rápida (esbuild, Vite, tsx) para transpilación y ejecución.
Las herramientas modernas de build no reemplazan a tsc sino que lo complementan. La combinación de un transpilador rápido para el ciclo de desarrollo con tsc --noEmit para la verificación de tipos ofrece el mejor equilibrio entre velocidad de iteración y seguridad de tipos.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, TypeScript es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de TypeScript
Explora más contenido relacionado con TypeScript y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Comprender el papel de esbuild como transpilador rápido de TypeScript. Configurar Vite como servidor de desarrollo y herramienta de build. Conocer SWC como alternativa basada en Rust. Usar tsx como reemplazo moderno de ts-node. Comparar tsc, esbuild y swc para elegir la herramienta adecuada.