Configuración de TypeScript Monorepo

Monorepo es un modelo de desarrollo que coloca múltiples proyectos en un mismo repositorio de código.

TypeScript admite Monorepo mediante referencias de proyectos y herramientas, permitiendo gestionar múltiples paquetes de manera eficiente.


Diagrama SVG: Estructura de Monorepo Contexto Título Estructura del proyecto Monorepo Directorio raíz Directorio raíz (root) package.json | tsconfig.json | lerna.json | turbo.json Directorio de paquetes Directorio packages/ Paquete 1 utils Paquete 2 ui-components Paquete 3 hooks Paquete 4 app Parte inferior: herramientas Herramientas de gestión: npm workspaces | yarn workspaces | pnpm | lerna | turbo Marcador de flecha

¿Por qué necesitas Monorepo?

Cuando el proyecto contiene múltiples paquetes (como bibliotecas de utilidades, bibliotecas de componentes, aplicaciones), el método tradicional requiere mantener múltiples repositorios de código.

Monorepo coloca todos los paquetes en el mismo repositorio, lo que facilita compartir código y unifica la gestión de versiones.

La función de referencias de proyectos de TypeScript hace que la verificación de tipos y la compilación de proyectos Monorepo sean más eficientes.

Concepto:Monorepo (repositorio único) coloca múltiples proyectos relacionados en el mismo repositorio de código, facilitando el intercambio de código y el desarrollo coordinado.


pnpm Workspace

pnpm es un gestor de paquetes moderno que admite de forma nativa la funcionalidad de Workspace.

package.json de la raíz

{
    "name": "my-monorepo",
    "version": "1.0.0",
    "private": true,

    // Habilitar pnpm workspace
    "packages": [
        "packages/*"
    ],

    // Dependencias de desarrollo
    "devDependencies": {
        "typescript": "^5.0.0"
    },

    // Scripts
    "scripts": {
        "build": "pnpm -r run build",
        "clean": "pnpm -r run clean",
        "type-check": "pnpm -r run type-check"
    }
}

pnpm:La funcionalidad de Workspace de pnpm puede vincular automáticamente los paquetes del directorio packages.


Estructura del proyecto

Crear la estructura de directorios del proyecto Monorepo.

Estructura de directorios

my-monorepo/
├── packages/
│   ├── utils/# Paquete de utilidades
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   │
│   ├── ui-components/# Paquete de componentes UI
│   │   ├── src/
│   │   │   ├── Button.tsx
│   │   │   └── index.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   │
│   └── app/# Aplicación
│       ├── src/
│       │   └── index.tsx
│       ├── package.json
│       └── tsconfig.json
│
├── package.json# Configuración de la raíz
├── tsconfig.base.json# Configuración básica
└── pnpm-workspace.yaml# Configuración de pnpm

packages:Todos los paquetes se colocan en el directorio packages, y cada paquete tiene su propio package.json y tsconfig.json.


Configuración básica de TypeScript

Crear una configuración básica para que la usen todos los paquetes.

tsconfig.base.json

{
    // Opciones del compilador
    "compilerOptions": {
        // Versión objetivo
        "target": "ES2020",

        // Sistema de módulos
        "module": "ESNext",

        // Modo estricto
        "strict": true,

        // Omitir verificación de tipos de bibliotecas
        "skipLibCheck": true,

        // Habilitar interoperabilidad de módulos ES
        "esModuleInterop": true,

        // Forzar coherencia de mayúsculas y minúsculas en nombres de archivo
        "forceConsistentCasingInFileNames": true,

        // Resolución de módulos
        "moduleResolution": "bundler",

        // Resolver módulos JSON
        "resolveJsonModule": true,

        // Módulos aislados
        "isolatedModules": true,

        // No generar archivos de salida
        "noEmit": true
    }
}

Herencia:El tsconfig.json de cada paquete hereda la configuración básica y solo sobrescribe las opciones que necesitan personalizarse.


Configuración del paquete de utilidades

Configurar TypeScript para el paquete de utilidades.

packages/utils/tsconfig.json

{
    // Heredar configuración básica
    "extends": "../../tsconfig.base.json",

    // Opciones del compilador
    "compilerOptions": {
        // Directorio de salida
        "outDir": "./dist",

        // Directorio de archivos de declaración
        "declarationDir": "./dist/types",

        // Generar archivos de declaración
        "declaration": true,

        // Generar declaraciones del archivo de entrada
        "declarationMap": true,

        // Forma de exportación de módulos
        "module": "ESNext",

        // Habilitar referencias de proyectos
        "composite": true
    },

    // Archivos incluidos
    "include": ["src/**/*"],

    // Archivos excluidos
    "exclude": ["node_modules", "dist", "**/*.test.ts"]
}

composite:Después de habilitar las referencias de proyectos, TypeScript puede compilar este paquete de forma incremental.


Configuración de la aplicación

Configurar TypeScript para la aplicación principal y hacer referencia a otros paquetes.

packages/app/tsconfig.json

{
    // Heredar configuración básica
    "extends": "../../tsconfig.base.json",

    // Opciones del compilador
    "compilerOptions": {
        // Directorio de salida
        "outDir": "./dist",

        // Configuración de JSX
        "jsx": "react-jsx",

        // Alias de ruta
        "baseUrl": ".",
        "paths": {
            "@my-utils/*": ["../utils/src/*"],
            "@my-ui/*": ["../ui-components/src/*"]
        }
    },

    // Referencias de proyectos
    "references": [
        { "path": "../utils" },
        { "path": "../ui-components" }
    ],

    // Archivos incluidos
    "include": ["src/**/*"],

    // Archivos excluidos
    "exclude": ["node_modules", "dist"]
}

Alias de ruta:Se pueden configurar alias de ruta para hacer referencia directamente a otros paquetes del mismo repositorio.


Dependencias entre paquetes

Declarar dependencias de paquetes del mismo repositorio en package.json.

packages/app/package.json

{
    "name": "@my-org/app",
    "version": "1.0.0",
    "private": true,

    "dependencies": {
        // Hacer referencia a paquetes del mismo repositorio
        "@my-org/utils": "workspace:*",
        "@my-org/ui-components": "workspace:*",

        // Dependencias externas
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
    },

    "devDependencies": {
        // Dependencias de desarrollo
        "@types/react": "^18.2.0",
        "typescript": "^5.0.0"
    }
}

workspace:Usa workspace:* para apuntar a otros paquetes del mismo repositorio, y pnpm lo resolverá automáticamente.


Scripts de compilación

Crear scripts de compilación unificados para el Monorepo.

package.json de la raíz

{
    "scripts": {
        // Compilar todos los paquetes
        "build": "pnpm -r run build",

        // Limpiar todos los artefactos de compilación
        "clean": "pnpm -r run clean",

        // Verificación de tipos
        "type-check": "pnpm -r run type-check",

        // Probar todos los paquetes
        "test": "pnpm -r run test",

        // Compilación incremental
        "build:watch": "pnpm -r --parallel run build:watch",

        // Iniciar la aplicación
        "dev": "pnpm --filter @my-org/app run dev"
    }
}

pnpm -r:Ejecuta recursivamente los scripts del mismo nombre en todos los paquetes.


Notas importantes

  • Convención de nombres de paquetes:Usar el formato @org-name/package
  • Versiones independientes:Cada paquete puede tener su propia gestión de versiones independiente
  • Protocolo workspace:Usar workspace:* para referenciar paquetes del mismo repositorio
  • Orden de compilación:Los paquetes de los que se depende deben compilarse primero

Mejores prácticas:Monorepo es adecuado para gestionar múltiples proyectos relacionados, ya que puede mejorar significativamente la reutilización de código y la eficiencia del desarrollo.


Resumen

Monorepo es el patrón recomendado para la gestión de proyectos frontend modernos.

  • pnpm Workspace:Compatibilidad nativa con Monorepo
  • Referencias de proyectos:Compilación incremental
  • Alias de ruta:Referencia conveniente a paquetes del mismo repositorio
  • Gestión unificada:Configuración y dependencias compartidas

Recomendación:Cuando el proyecto contenga múltiples paquetes relacionados, considera la solución Monorepo como prioridad.

Otras extensiones