web-dev-qa-db-fra.com

Comment utiliser les espaces de travail Yarn avec TypeScript et les dossiers Out?

J'essaie de mettre en place un monorepo en utilisant du fil. Je ne sais pas comment configurer TypeScript avec des références de projet pour que les choses se résolvent correctement.

Par exemple, si j'ai une structure de dossiers comme

/cmd
/client

Et je veux que cmd dépende de client Je pourrais avoir:

cmd/tsconfig.json:

{
  "compilerOptions": {
    "types": ["reflect-metadata", "jest"],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": "node",
    "declaration": true,
    "importHelpers": true,
    "composite": true,
    "target": "esnext"
    "sourceRoot": "src",
    "outDir": "dist"
  },
  "references": [
    {
      "path": "../client"
    }
  ],
  "include": [
    "src/**/*"
  ]
}

avec un package.json

{
  "name": "cmd",
  "version": "1.0.0",
  "dependencies": {
    "client": "^1.0.0",
  }
}

Dans ce modèle, cmd et client sont compilés avec un champ outDir et sourceRoot défini dans leur tsconfig. Cela signifie que tout leur javascript compilé va dans le dist/ sous-dossier de cmd/dist et client/dist

Si maintenant j'essaie de référencer une classe de client dans cmd comme

import Foo from 'client/src/foo'

Le IDE est parfaitement heureux de résoudre ce problème car il semble que son mappé via la propriété TypeScript references.

Cependant, le javascript compilé se résume à un

const foo_1 = require("client/src/foo");

Cependant, le javascript réellement construit est dans client/dist/src/foo, donc au moment de l'exécution, cela ne fonctionne jamais.

D'un autre côté, si je n'utilise pas sourceRoots et outDirs et que le javascript est aligné avec les fichiers TypeScript dans le même dossier, tout fonctionne (mais rend le dépôt sale et nécessite des gitignores personnalisés pour exclure des choses)

Quelqu'un peut-il nous éclairer sur la façon de configurer correctement un monorepo TypeScript 3.x avec des espaces de travail de fil de telle sorte que les choses fonctionnent simplement?

9
devshorts

J'ai créé un Github Repository pour le rendre plus facile à suivre la description de code suivante:


Code Description

TypeScript Project References permet de compiler un projet TypeScript composé de plusieurs projets TypeScript plus petits, chaque projet ayant un tsconfig.json fichier. (Source: Documentation de références du projet )


Configuration de TypeScript

Nous avons une racine tsconfig.json fichier qui gère uniquement ses sous-projets. La propriété references spécifie les répertoires qui contiennent chacun un tsconfig.json fichier. Si nous construisons maintenant le projet avec le --build option (tsc --build tsconfig.json) puis nous avons spécifié les projets à compiler, mais nous n'avons pas spécifié l'ordre de construction dans lequel les projets devraient être compilés.

{
  "references": [
    { "path": "./client" },
    { "path": "./cmd" }
  ],
  "files": [],
  "include": [],
  "exclude": ["**/node_modules"]
}


Pour spécifier correctement l'ordre de construction , nous devons ajouter une propriété references à la propriété cmd/tsconfig.json fichier. Cela indique au compilateur qu'il doit d'abord compiler client/ avant de compiler cmd/:

cmd/tsconfig.json:

{
  "extends": "../tsconfig.packages.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist"
  },
  "references": [
    {
      "path": "../client"
    }
  ]
}

Ordre de construction

client/
  ^
  |
  |
 cmd/


Configuration des nœuds

La meilleure pratique est que chaque sous-projet possède son propre package.json fichier avec la propriété main et la propriété (name défini. Dans notre exemple, les deux packages (cmd/ et client/) ont une propriété main pointant vers index.js fichier dans le répertoire TypeScript outDir (cmd/dist/index.js et client/dist/index.js).

Structure du projet:

tsconfig.json
cmd/
    tsconfig.json
    package.json
    src/
        index.ts
    dist/  #artifacts
        index.js
client/
    tsconfig.json
    package.json
    src/
        index.ts
    dist/  #artifacts
        index.js

client/packages.json

{
  "name": "client",
  "version": "1.0.0",
  "main": "dist/index",
  ...
}

Il est important que nous ajoutions le client/ en tant que dépendance à cmd/packages.json pour que l'algorithme de résolution du module puisse trouver le client/dist/index.js lorsque nous l'importons dans notre code TypeScript import Foo from 'client';:

cmd/packages.json

{
  "name": "cmd",
  "version": "1.0.0",
  "main": "dist/index",
  "dependencies": {
    "client": "1.0.0" // important
  }
}

cmd/src/index.ts

import Foo from 'client';

console.log(Foo())


Configuration du fil

La configuration du fil est facile. Yarn ajoute tous les packages sous node_modules au lieu de:

  • cmd/node_modules
  • client/node_modules

Pour activer le fil espaces de travail ajoutez la propriété workspaces et le private: true propriété au <root>/package.json fichier.

<root>/package.json

{
  "private": true,
  "workspaces": [
    "cmd",
    "client"
  ],
  "name": "yarn_workplace",
  "version": "1.0.0"
  ...
}


Le cmd/ et client/ les packages sont symlinked sous <root>/node_modules/ répertoire:

yarn node_modules


Remarques

  • Pour activer la navigation dans le code, il faut d'abord construire le projet
  • Chaque paquet vit seul. Le cmd/ le package utilise le fichier de définition client/dist/index.d.ts pour les informations de type au lieu d'utiliser directement les fichiers TypeScript.
15
a1300