Monorepositorio con TypeScript: organización de código en la práctica
\n\nEn el desarrollo web moderno, especialmente al trabajar con TypeScript, los desarrolladores a menudo se enfrentan a un dilema: almacenar todo el código en un solo repositorio (monorepositorio) o dividirlo en muchos repositorios pequeños (polirepositorio). Para proyectos medianos y grandes, donde la reutilización del código y una configuración unificada son importantes, el monorepositorio se convierte en el estándar de facto. En este artículo, analizaremos cómo organizar correctamente un monorepositorio en TypeScript, desde la estructura básica hasta técnicas avanzadas.
\n\n¿Qué es un monorepositorio y para qué sirve?
\n\nUn monorepositorio es un enfoque en el que el código de varios proyectos (paquetes, bibliotecas, aplicaciones) se almacena en un solo repositorio. En el contexto de TypeScript, esto es especialmente conveniente, ya que permite:
\n\n- \n
- Reutilizar tipos e interfaces entre diferentes partes del sistema sin publicar en npm. \n
- Simplificar la refactorización: un cambio en un paquete se valida automáticamente en todos los dependientes. \n
- Tener una configuración unificada para linter, formateador y compilador. \n
- Simplificar CI/CD: un repositorio, un pipeline. \n
Entre las herramientas populares para trabajar con monorepositorios en TypeScript se destacan Nx, Turborepo y npm/yarn/pnpm workspaces. Consideraremos un enfoque que utiliza pnpm workspaces y TypeScript Project References, ya que es un conjunto mínimo y flexible.
\n\nEstructura del monorepositorio: configuración básica
\n\nVamos a crear una estructura típica de monorepositorio para un proyecto TypeScript. Supongamos que tenemos tres paquetes: core (tipos y utilidades comunes), server (backend) y web (frontend).
1. Configuración raíz
\n\nEmpecemos por la raíz del proyecto. Creemos un archivo package.json con workspace:
{\n "name": "my-monorepo",\n "private": true,\n "workspaces": [\n "packages/*"\n ],\n "scripts": {\n "build": "tsc -b",\n "clean": "tsc -b --clean",\n "lint": "eslint packages/*/src"\n }\n}\n\n\nLuego, configuremos el tsconfig.json raíz. Usaremos Project References, que es una característica clave de TypeScript para monorepositorios:
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "strict": true,\n "composite": true,\n "declaration": true,\n "declarationMap": true,\n "sourceMap": true,\n "outDir": "./dist",\n "rootDir": ".",\n "skipLibCheck": true\n },\n "references": [\n { "path": "./packages/core" },\n { "path": "./packages/server" },\n { "path": "./packages/web" }\n ]\n}\n\n\nImportante: la opción composite: true es obligatoria para los paquetes a los que otros paquetes hacen referencia. Habilita la compilación incremental y la generación de archivos .d.ts.
2. Configuración del paquete core
\n\nVayamos a packages/core. Creemos package.json:
{\n "name": "@my/core",\n "version": "1.0.0",\n "main": "dist/index.js",\n "types": "dist/index.d.ts",\n "scripts": {\n "build": "tsc -b"\n }\n}\n\n\nY el tsconfig.json para este paquete:
{\n "extends": "../../tsconfig.json",\n "compilerOptions": {\n "outDir": "./dist",\n "rootDir": "./src"\n },\n "include": ["src"]\n}\n\n\nCreemos un módulo simple src/index.ts:
export interface User {\n id: string;\n name: string;\n email: string;\n}\n\nexport function greet(user: User): string {\n return `Hello, ${user.name}!`;\n}\n\n\nAhora el paquete
Blogs
Book Recommendations
Leer también
Salarios de desarrolladores Java en Rusia: análisis del mercado (nivel avanzado)
Funciones Serverless en PHP: AWS Lambda Nivel Avanzado
Los 10 mejores frameworks de Go para desarrollo web: nivel avanzado
API GraphQL en C++: guía completa con ejemplos
Introducción a Go: por dónde empezar en 2025 — guía para principiantes