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?
J'ai créé un Github Repository pour le rendre plus facile à suivre la description de code suivante:
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 )
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/
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())
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:
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.