Búsqueda de sitios web

node.js - Problemas al construir un proyecto monorepo de TypeScript


Tengo un monorepo bastante simple. Está disponible en GitLab aquí. Esto usa yarn workspaces, TypeScript, Jest, ts-jest y ESLint con eslint-plugin-import.

Estoy tratando de construir correctamente los paquetes del proyecto usando TypeScript. Anteriormente, solo publicaba los archivos de TypeScript junto con su código JavaScript en el mismo directorio.

Mi intento de construir el proyecto está disponible en una solicitud de fusión de GitLab aquí

Ahora el repositorio sigue la siguiente estructura:

 |- example/
 |   |- index.ts
 |   |- package.json
 |   `- tsconfig.json
 |- packages/
 |   |- koas-core/
 |   |   |- src/
 |   |   |   `- index.ts
 |   |   |- package.json
 |   |   `- tsconfig.json
 |   |- koas-status-code/
 |   |   |- src/
 |   |   |   `- index.ts
 |   |   |- package.json
 |   |   `- tsconfig.json
 |   `- more similar workspaces…
 |- package.json
 |- tsconfig.json
 `- more configuration files…

Algunos paquetes dependen unos de otros. He logrado que las pruebas de Jest y eslint-plugin-import funcionen con esta configuración, pero estoy teniendo problemas para construir el proyecto.

El archivo raíz tsconfig.json se ve así:

{
  "compilerOptions": {
    "baseUrl": ".",
    "composite": true,
    "declaration": true,
    "module": "commonjs",
    "noEmit": true,
    "resolveJsonModule": true,
    "target": "esnext",
    "paths": {
      "koas-*": ["packages/koas-*/src"]
    }
  },
  "exclude": ["**/*.test.ts"]
}

Los archivos de espacio de trabajo tsconfig.json se ven así:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "lib"
  }
}

Cada espacio de trabajo tiene un script prepack definido en package.json que se ve así:

{
  "scripts": {
    "prepack": "tsc --noEmit false"
  }
}

El campo main se refiere a lib.

Si ejecuto yarn workspace koas-status-code prepack, obtengo el siguiente error:

tsc --noEmit false
error TS6059: File 'koas/packages/koas-core/src/SchemaValidationError.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/SchemaValidationError.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createDefaultValidator.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createDefaultValidator.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createMatcher.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createMatcher.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/index.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/index.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6307: File 'koas/packages/koas-core/src/SchemaValidationError.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.

error TS6307: File 'koas/packages/koas-core/src/createDefaultValidator.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.

error TS6307: File 'koas/packages/koas-core/src/createMatcher.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.

error TS6307: File 'koas/packages/koas-core/src/index.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.


Found 12 errors.

También he probado este tsconfig.json para koas-status-code:

{
  "extends": "../../tsconfig.json",
  "include": ["src"],
  "references": [{ "path": "../koas-core" }],
  "compilerOptions": {
    "outDir": "lib"
  }
}

Esto construye el espacio de trabajo, pero todavía me da el siguiente error:

tsc --noEmit false
src/index.ts:1:23 - error TS6305: Output file '/home/remco/Projects/koas/packages/koas-core/lib/src/index.d.ts' has not been built from source file '/home/remco/Projects/koas/packages/koas-core/src/index.ts'.

1 import * as Koas from 'koas-core';
                        ~~~~~~~~~~~


Found 1 error.

¿Cómo arreglo esto?

Respuesta #1

He encontrado una solución para este problema basada en https://github.com/NiGhTTraX/lerna-ts.

El proyecto ahora contiene un archivo llamado tsconfig.build.json en la raíz del proyecto. Este archivo especifica las opciones del compilador y que los archivos de prueba y compilación deben excluirse del proceso de construcción.

{
  "compilerOptions": {
    "declaration": true,
    "module": "commonjs",
    "resolveJsonModule": true,
    "target": "esnext"
  },
  "exclude": ["**/*.test.ts", "**/lib"]
}

Otro archivo en la raíz es tsconfig.json. Este archivo se utiliza para la verificación de tipos fuera del proceso de compilación, por ejemplo, por Jest y VSCode. Este archivo extiende la configuración de compilación. Incluye pruebas sobrescribiendo la configuración exclude extendida. También contiene noEmit: true, porque los procesos que usan TypeScript durante el desarrollo no deberían generar nada. Además, contiene las opciones del compilador baseUrl y paths que se necesitan para resolver los archivos fuente de TypeScript en tiempo de ejecución. Esto se debe a que el campo main en los archivos package.json de los paquetes hace referencia a lib, que contiene los archivos de salida.

{
  "extends": "./tsconfig.build.json",
  "compilerOptions": {
    "baseUrl": ".",
    "noEmit": true,
    "paths": {
      "koas-*": ["packages/koas-*/src"]
    }
  },
  "exclude": ["**/lib"]
}

Cada espacio de trabajo contiene un archivo tsconfig.build.json. Esto es necesario, porque requiere que las opciones src y outDir sean relativas al archivo tsconfig. Esto se utiliza para construir el proyecto. Es importante que este archivo no se llame tsconfig.json.

{
  "extends": "../../tsconfig.build.json",
  "include": ["src"],
  "compilerOptions": {
    "outDir": "lib"
  }
}

Cada espacio de trabajo también contiene un tsconfig.json. Esto se puede usar para sobrescribir las opciones del compilador para la verificación de tipos, por ejemplo, si un repositorio usaría los tipos dom. Esto podría omitirse.

{
  "extends": "../../tsconfig.json"
}

Cada espacio de trabajo tiene la siguiente sección scripts en package.json. Esto hace que TypeScript se compile cuando se construye el paquete.

  // …
  "scripts": {
    "prepack": "tsc --project tsconfig.build.json"
  }

Hay dos trabajos de CI para la verificación de tipos. Uno ejecuta tsc para asegurarse de que la verificación de tipos todavía funcione en las herramientas que usan estos tipos durante el desarrollo, y el otro se asegura de que la construcción de los paquetes no se rompa.

tsc:
  script:
    - yarn --frozen-lockfile
    - yarn workspaces run tsc

pack:
  script:
    - yarn --frozen-lockfile
    - yarn workspaces run pack
    - find packages -name '*.tgz' -exec mv {} ./ +
  artifacts:
    name: packages
    paths:
      - '*.tgz'

Artículos relacionados