Typescript: tsc ne devrait pas s'en soucier et échouer avec les fichiers ts en dehors de rootDir

Créé le 21 juil. 2016  ·  87Commentaires  ·  Source: microsoft/TypeScript

TypeScript : 2.0.0

J'ai un dossier fixtures qui contient des fichiers .ts . Dans mon tsconfig.json j'ai défini rootDir sur src qui contient tout mon code source (y compris le test).

Les fichiers de fixtures sont là pour les cas de test. tsc ne devrait pas se plaindre de leur existence et échouer la compilation.

Working as Intended

Commentaire le plus utile

Bleh, ça marche vraiment comme prévu ? Je viens de tomber sur ça, j'ai dit à dactylographié que ma source était toute dans un dossier particulier (via rootDir ) et ensuite il a _ignoré complètement ce que je lui ai dit_ parce que j'avais un seul fichier avec un .ts extension se trouvant en dehors de ce dossier.

Cela ressemble vraiment à une erreur, si je dis au compilateur où se trouve ma source via rootDir , il ne devrait pas ignorer complètement ce paramètre et modifier la structure de mon dossier de sortie car il pense que j'ai peut-être fait quelque chose de mal. Il devrait simplement ignorer tous les fichiers qui ne sont pas dans rootDir . Alternativement, il devrait échouer, ne pas continuer à émettre une sortie qui ne correspond pas du tout à la structure de dossier de sortie souhaitée!


Pour toute personne venant après moi, ce qui suit fera ce que vous voulez réellement :

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

Tous les 87 commentaires

Pour me déplacer, j'ajoute "exclude" à mon tsconfig.json

le rootDir est utilisé pour construire la structure du dossier de sortie. tous les fichiers doivent être sous rootDir pour que le compilateur sache où écrire la sortie. sans cette contrainte, s'il y a des fichiers qui ne sont pas sous rootDir, le compilateur a deux options 1. soit ils seront émis à un endroit totalement inattendu, soit 2. pas émis du tout. Je dirais qu'un message d'erreur est bien mieux qu'un échec silencieux.

@mhegazy Merci pour les éclaircissements. De nom rootDir je l'ai pris comme répertoire racine du code source, un peu comme baseURL pour le navigateur. Je ne savais pas que c'était uniquement pour la structure des dossiers de sortie.

Voici mon tsconfig.json :

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "noImplicitAny": true,
        "rootDir": "src",
        "outDir": "build"
    },
    "exclude": [
        ".idea",
        "build",
        "node_modules",
        "typings/globals",
        "typings/modules"
    ]
}

Ma structure de dossier ressemble à ceci :

  • projet

    • construire

    • node_modules (lien symbolique vers ../node_modules)

    • node_modules

    • src

Je veux que mes fichiers .ts dans le dossier src soient compilés et sortis avec les mêmes structures de dossiers dans le dossier de construction. Je fais cela pour pouvoir définir la racine de mon document dans le dossier de construction et garder mon src hors de la racine de la doc. Je reçois des messages d'erreur sur les fichiers .ts dans le dossier node_modules, les mêmes messages d'erreur que OP. Remarque ci-dessus, j'ai exclu node_modules. Pourquoi tsc s'en plaint-il ?

@HillTravis, votre problème semble être le même que https://github.com/Microsoft/TypeScript/issues/9552.

@mhegazy, je ne suis pas sûr que ce soit la même chose. Oui, ma structure inclut un lien symbolique, mais n'importe quel endroit où ce lien symbolique existe doit être ignoré.

Dans #9552, il n'y a pas de dossier src, ce qui signifie que le dossier node_modules existe dans le chemin en cours de construction. Dans mon scénario, le répertoire racine que tsc devrait examiner est src, qui ne contient pas node_modules. Il ne devrait donc pas du tout regarder ce dossier. En plus de cela, j'ai explicitement exclu le dossier node_modules via mon tsconfig.json. Il faut donc l'ignorer doublement. J'ai également exclu le dossier build , et cela devrait couvrir le lien symbolique vers node_modules à l'intérieur.

De plus, dans #9552, il n'y avait aucune mention des messages d'erreur ou de l'échec de la compilation.

Je dois également mentionner que j'utilise TypeScript 1.8.10.

Plus précisément, les messages d'erreur lisent :

erreur TS6059 : le fichier '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.module.ts' n'est pas sous 'rootDir' '/Users/thill/Projects/ nrc/client/src'. 'rootDir' devrait contenir tous les fichiers source.

erreur TS6059 : le fichier '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.ts' n'est pas sous 'rootDir' '/Users/thill/Projects/nrc/ client/src'. 'rootDir' devrait contenir tous les fichiers source.

erreur TS6059 : le fichier '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/timepicker-event-interface.ts' n'est pas sous 'rootDir' '/Users/thill/Projects/ nrc/client/src'. 'rootDir' devrait contenir tous les fichiers source.

@HillTravis, vous pouvez me faire confiance sur celui-ci :) c'est notre gestion incohérente des liens symboliques qui désactive le compilateur. nous suivons les liens symboliques uniquement pour la résolution du module de nœud, puis utilisons ce nom comme nom de fichier ; Ensuite, nous effectuons une vérification pour nous assurer que tous les fichiers se trouvent dans le répertoire source en utilisant le chemin réel, au lieu du chemin spécifié par l'utilisateur. et c'est ce qui génère l'erreur.

En guise de test, j'ai essayé de supprimer le lien symbolique. En fait, j'ai supprimé tout le dossier build . Ensuite, j'ai réexécuté tsc et j'ai toujours vu l'erreur.

Au cours de tests supplémentaires, j'ai essayé de commenter l'importation dans le code et les utilisations de ce module de nœud particulier (ng2-datetime) et l'erreur a disparu. Ce n'est donc que lorsque j'essaie d'importer ce module de nœud que je vois l'erreur, quel que soit le lien symbolique.

Si vous regardez la source de ce package sur GitHub, vous verrez que le fichier package.json a le paramètre "main" défini sur "ng2-datetime.js", bien que l'auteur ait également publié le fichier .ts avec le même Nom. Cela semble être à l'origine du problème. Si je crée des fichiers .d.ts et supprime les fichiers .ts, le problème disparaît. Il s'est compilé sans problème même après avoir rajouté le lien symbolique.

Donc, avec tout le respect, je ne vois pas comment ce problème pourrait être lié au lien symbolique en particulier. Il semble que cela ne cause généralement que des problèmes lorsque l'auteur inclut les fichiers .ts dans le package.

Savez-vous s'il existe une solution de contournement pour cela? L'OP ci-dessus a dit qu'il avait contourné le problème en ajoutant "exclude" au tsconfig.json. J'ai déjà exclu le répertoire, mais il essaie toujours de le compiler.

Savez-vous s'il existe une solution de contournement pour cela? L'OP ci-dessus a dit qu'il avait contourné le problème en ajoutant "exclude" au tsconfig.json. J'ai déjà exclu le répertoire, mais il essaie toujours de le compiler.

Cela peut être lié à un autre, mais je ne le trouve pas pour le moment. Lors de la résolution d'un type, tsc essaie toujours de le rechercher à partir de node_modules , alors qu'il n'y est pas (lié à typings ).

"tsc ne devrait pas s'en soucier et échouer avec les fichiers ts en dehors de rootDir" Je suis d'accord.

Je ne peux pas comprendre pourquoi tapuscrit examinerait les fichiers JS en dehors du rootDir, car c'est là que devrait se trouver toute la source.
Le message d'erreur dit "'rootDir' devrait contenir tous les fichiers source", alors tout ce qui se trouve en dehors de ce répertoire ne doit pas être attendu ou supposé être un fichier source, en ce qui concerne TS !

S'il s'agit de « Travailler comme prévu », alors quelle est exactement l'intention ou la motivation de ce comportement ? Existe-t-il un cas où TS voudrait compiler des fichiers source situés en dehors du rootDir ?

D'un autre côté, l'ajout d'une section "include" dans tsconfig résout le problème. Lorsqu'il est fourni avec des fichiers ou des répertoires à inclure, TS ne cherche pas d'autres fichiers en dehors de cela.

avec tapuscrit 1.8.10

J'avais un dossier node_modules dans mon homedir ~/node_modules . L'exécution de tsc partir de mon dossier de projet ~/projects/myProject/ provoqué une plainte de typescript à propos des fichiers suivants

../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/config.d.ts(29,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(36,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(68,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(75,111): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/request.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/services/glacier.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.

très déroutant - même si je ne sais pas pourquoi j'avais un dossier de modules de nœud dans mon répertoire personnel pour commencer.

@iwllyu pouvez-vous vérifier votre projet sur [email protected] et déposer un nouveau problème si vous rencontrez toujours des problèmes.

J'ai toujours le problème avec 2.1.4 bien qu'il se plaint d'un ensemble de fichiers différent

Using tsc v1.8.10
../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(27,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(34,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(66,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(73,111): error TS1110: Type expected.
Using tsc v2.1.4
../../node_modules/aws-sdk/lib/config.d.ts(38,37): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/request.d.ts(164,16): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/s3/managed_upload.d.ts(15,16): error TS2304: Cannot find name 'Promise'.

Je vais créer un projet pour isoler le cas de test

Eh bien, j'ai essayé avec un nouveau projet et cela n'arrivait pas. Comme il s'agit d'un projet plus ancien et que je l'ai déjà corrigé en supprimant le dossier node_modules supplémentaire, je ne passerai plus de temps à essayer de le recréer. Merci pour l'aide!

A propos de cette affaire. Si tout ce que vous importez sont des types (comme si je surfais vraiment sur cette vague "front-typescript, back-typescript") de l'extérieur - peut-être que tsc peut distinguer ce que je fais?
Je ne partage que les types de mes entités du backend à mon application frontend. Sortie bien sûr sans types ni importations de ces classes (car elles ne sont utilisées que pour le temps de compilation et intellisense).

J'ai eu ça aussi.
Le texte dactylographié est trop contraignant pour notre équipe - compte tenu du flux maintenant.

les gars, une résolution à ce sujet maintenant? en utilisant des types du code client à l'intérieur du code backend et autrement.

quelle est la meilleure option ? copier-coller ici et là et modifier si je change de type ?

faire un répertoire racine pour 2 projets n'est pas une option, car pourquoi le backend tsconfig.json aura des informations sur jsx et compilera dans commonjs quand je peux utiliser es2015

Est-ce que baseUrl fonctionne pour vous ?

@unional ne changera pas baseUrl cassera toutes les importations node_modules - nécessitant de ne pas écrire

import * as request from "superagent";

mais

import * as request from "node_modules/superagent/..something";

?

Bleh, ça marche vraiment comme prévu ? Je viens de tomber sur ça, j'ai dit à dactylographié que ma source était toute dans un dossier particulier (via rootDir ) et ensuite il a _ignoré complètement ce que je lui ai dit_ parce que j'avais un seul fichier avec un .ts extension se trouvant en dehors de ce dossier.

Cela ressemble vraiment à une erreur, si je dis au compilateur où se trouve ma source via rootDir , il ne devrait pas ignorer complètement ce paramètre et modifier la structure de mon dossier de sortie car il pense que j'ai peut-être fait quelque chose de mal. Il devrait simplement ignorer tous les fichiers qui ne sont pas dans rootDir . Alternativement, il devrait échouer, ne pas continuer à émettre une sortie qui ne correspond pas du tout à la structure de dossier de sortie souhaitée!


Pour toute personne venant après moi, ce qui suit fera ce que vous voulez réellement :

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

J'ai dit à dactylographié que ma source était toute dans un dossier particulier (via rootDir)

Ce n'est pas ce que signifie rootDir ! rootDir signifie "Utiliser ce dossier comme base relative pour calculer les chemins dans outDir ". Quels fichiers font partie de votre compilation est une question distincte à laquelle répond files et/ou include / exclude

Même si j'accepte cela, le comportement actuel est toujours en erreur IMO. Si j'ai des fichiers TS en dehors du répertoire spécifié, alors rootDir ne sera _pas_ la base pour calculer les chemins dans outDir , ce qui signifie que la configuration que j'ai spécifiée sera complètement ignorée.

Je pense qu'un échec grave serait bien mieux car le compilateur pense effectivement que j'ai donné une configuration invalide. Ignorer la configuration lorsqu'elle n'est pas valide n'est (IMO) pas la bonne façon de gérer cette classe d'échec.

Exemple de message d'erreur qui serait beaucoup plus clair (avec une panne matérielle) :

TSC a trouvé des fichiers dactylographiés en dehors de rootDir et ne peut donc pas procéder à la compilation. Modifiez rootDir pour inclure tous les fichiers dactylographiés, ou excluez les fichiers en dehors de rootDir, ou n'incluez que les fichiers à l'intérieur de rootDir.

Remarque : une grande partie de la raison pour laquelle le comportement actuel de rootDir semble très mauvais est précisément parce qu'il n'a pas de sens d'avoir des fichiers en dehors de rootDir. Quand on se demande (ou au compilateur) ce que cela signifie de compiler des fichiers en dehors de rootDir la seule réponse est "ça n'a pas de sens". Par conséquent, on arrive à la conclusion naturelle que rootDir spécifie également sourceDir.

Le mal est dans le nom. Cela signifie vraiment relativePathBaseDir ou quelque chose comme ça.

J'ai également remarqué que include signifie normalement "regardez ici aussi" mais dans ce cas, cela signifie "regardez seulement ici".
Je serais sensé qu'il ait un autre nom et soit obligatoire.

OMI, ce commentaire doit être particulièrement pris en compte pour confirmer qu'il s'agit bien d'un bogue et doit être rouvert en tant que tel :

Remarque : une grande partie de la raison pour laquelle le comportement actuel de rootDir semble très mauvais est précisément parce qu'il n'a pas de sens d'avoir des fichiers en dehors de rootDir. Quand on se demande (ou au compilateur) ce que cela signifie de compiler des fichiers en dehors de rootDir la seule réponse est "ça n'a pas de sens".

En effet, cela n'a pas de sens . Les "fichiers sources en dehors de rootDir " ne sont tout simplement

+100 sur le fait qu'il s'agit d'un bug (un méchant en fait). Considérez la structure de répertoire suivante :

- src/
  - module.ts
- test/
  - module.test.ts
- out/
  - module.js

Je voudrais que tsc ne compile que le src , car j'exécute des tests avec ts-node . Avoir rootDir: 'src' provoquera une erreur de compilation actuellement. Si vous marquez des tests et d' autres choses que vous ne l' intention d'exécuter avec ts-node (ou même compiler séparément peut - être?) Comme « exclus », alors les mauvaises choses commencent à se produire (par exemple vscode mise en tests )

En fait, aucune combinaison de rootDir , excluded et toutes les autres options ne satisfait toutes les exigences (excluez les tests de la compilation tout en pouvant les exécuter et travailler avec eux).

Et je ne pense pas vraiment que mon cas d'utilisation soit unique, il vaut donc la peine de reconsidérer l'étiquette "travailler comme prévu", au moins du point de vue UX.

La configuration src / test / out était un scénario clé abordé par les références du projet

J'ai trouvé ce problème parce que je cherchais pourquoi typescript essayait de compiler mon fichier webpack.config.js après avoir défini rootDir .

J'ai dit à dactylographié que ma source était toute dans un dossier particulier (via rootDir)

Ce n'est pas ce que rootDir signifie ! rootDir signifie "Utiliser ce dossier comme base relative pour calculer les chemins dans outDir". Quels fichiers font partie de votre compilation est une question distincte qui est répondue par des fichiers et/ou inclure/exclure

C'est la réponse ! Les documents pour rootDir disent

Spécifie le répertoire racine des fichiers d'entrée

Ce que j'ai pris pour signifier "fichiers _source_ d'entrée". Je recommande que le commentaire de @RyanCavanaugh remplace l'explication actuelle de cette option.

Lien ici - https://github.com/Microsoft/TypeScript/issues/11299 est un doublon de ce problème. (Solution : utilisez include/exclude pour spécifier les fichiers à compiler, rootDir ne spécifie PAS les fichiers à compiler.)

@mhegazy Souhaitez-vous ajouter un commentaire sur ce fil à cet effet? Cela semble être ce à quoi le demandeur fait référence (perplexe quant à la raison pour laquelle TS examine des fichiers en dehors de RootDir, même malentendu quant à la signification de rootDir).

Je suis également confronté à ce problème et je n'ai pas réussi à le résoudre.

La compilation tsc parcourt l'arborescence de mon répertoire inclus et dans les dossiers parents, provoquant des erreurs de type en double.

J'ai une structure de dossiers imbriqués qui ressemble à ceci :

└─src
└─package.json
└─node_modules
└─tsconfig.json
└─example
│ └─src
│ └─package.json
│ └─node_modules
│ └─tsconfig.json

Maintenant, lorsque j'essaie d'exécuter tsc à partir du répertoire d'exemple, j'obtiens l'erreur suivante :

node_modules/@types/react/index.d.ts:2809:14 - error TS2300: Duplicate identifier 'LibraryManagedAttributes'.

2809         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                  ~~~~~~~~~~~~~~~~~~~~~~~~

  ../node_modules/@types/react/index.d.ts:2814:14
    2814         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                      ~~~~~~~~~~~~~~~~~~~~~~~~
    'LibraryManagedAttributes' was also declared here.

Comme vous pouvez le voir par l'erreur, tsc parcourt l'arborescence de haut en bas du dossier d'exemple et recherche dans le dossier node_modules du répertoire parent ! Ce qui est encore pire, c'est que j'ai essayé d'ignorer explicitement le répertoire node_modules parent avec peu d'effet.

Voici le tsconfig du répertoire d'exemple :

{
  "compilerOptions": {
    "target": "es5",
    "experimentalDecorators": true,
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "moduleResolution": "node",
    "lib": ["es2017", "dom"],
    "jsx": "react"
  }
,
  "typeRoots": [
    "./node_modules/@types"
  ],
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules",
    "../node_modules"
  ]
}

Comment puis-je résoudre ce problème ? Rien de ce qui précède ne semble fonctionner pour moi

@lexwebb J'ai eu le même problème, vérifiez dans vos fichiers yarn.lock que @types/react ont les mêmes versions.
Voir https://stackoverflow.com/questions/52399839/typescript-duplicate-identifier-librarymanagedattributes.

J'ai atterri ici parce que mon dossier d'actifs contient un fichier vidéo "MPEG Transport Stream" avec l'extension .ts ce qui a fait planter tsc même si le dossier n'était pas dans mon chemin rootDir 😄

Je l'ai corrigé en ajoutant le dossier assets dans les chemins exclude mais c'était un comportement dérangeant 🤔

Il s'avère donc que j'avais une version légèrement différente de React dans le paquet parent et le paquet enfant json. Faire correspondre les versions exactement a supprimé le problème. Encore une douleur que vous ne pouvez pas exclure de la vérification du type de formulaire des répertoires parents.

Je suppose que cela ne sera jamais réglé. Je viens de rencontrer le même problème. Comment cela "fonctionne comme prévu" me dépasse. Je suppose que l'intention était de faire fonctionner le compilateur d'une manière absurde.

D'après ma propre expérience personnelle, la raison pour laquelle une construction dactylographiée s'éloigne de votre arbre rootDir et essaie de construire des choses auxquelles vous ne vous attendez pas est le fait que vous avez (délibérément ou par inadvertance) référencé directement ou indirectement quelque chose dans ce zone à partir de votre rootDir . Si vous faites cela, la construction suivra l'arborescence de référence, que vous ayez ou non essayé d'exclure la zone contenant le fichier référencé. Parfois, cela peut être un PITA essayant de découvrir comment/où vous l'avez fait - mais invariablement je trouve que c'est de ma faute - pas la faute de tsc . Il fait simplement ce que je lui ai dit de faire.

Chaque fois que cela me frappe, c'est à cause des types. J'importe une interface ou quelque chose qui réside dans un fichier qui importe quelque chose d'autre qui réside dans un fichier qui importe quelque chose d'autre......jusqu'à ce que je finisse par importer quelque chose qui réside dans un fichier en dehors de mon rootDir et très souvent dans quelque chose que j'essaie d'exclure explicitement dans ma configuration.

HTH certains de vos aller à la racine de votre douleur. Aucune quantité de configuration ne vous en sortira - il vous suffit de garder un contrôle strict de votre structure d'importation.

@kpturner Cela semble super raisonnable, mais - un projet de test barebones sans importations inter-dossiers produira le comportement dont tout le monde se plaint.

Vraiment? Que je n'ai jamais vu :)

Les dossiers exclus sont toujours exclus dans tous mes projets sauf lorsque les circonstances auxquelles je fais allusion sont présentes.

Y a-t-il des exemples nus sur ce fil? Difficile à dire depuis mon téléphone.

Toutes mes excuses, l'exclusion ne fait pas partie de la situation « nue » à laquelle je fais référence. Je note simplement que les importations ne semblent pas être une cause du comportement (bien que cela aurait plus de sens si tel était le cas).

c'est-à-dire que la compilation de quelque chose comme ceci entraînera une erreur.

-src / src.ts <- no imports -test / test.ts -out -tsconfig.json {"rootDir": "src", "outDir": "out"}

Mais si votre tsconfig.json ressemble à ça, je m'attendrais à ce que typescript compile tout dans le répertoire src et tout dans le répertoire test . Si vous voulez seulement qu'il transpile uniquement des éléments dans src et qu'il soit affiché dans le répertoire out , alors votre tsconfig.json devrait être

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    }
}

Ensuite, cela générerait une erreur TS6059 car vous avez des fichiers en dehors du rootDir . Vous devez donc exclure ceux-ci :

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    },
    "exclude": [
        "test"
    ]
}

qui, une fois transpilé, générera un dossier appelé out avec un sous-dossier de src contenant src.js . Le dossier test est complètement ignoré. C'est ce à quoi je m'attendrais - non ?

Euh, en effet, mon exemple tsconfig aurait dû inclure rootDir et outDir sous compilerOptions comme vous le montrez dans votre premier exemple. Vous avez également raison de dire que lorsque vous excluez test , test et ses fichiers sont exclus. À l'origine, je pensais que vous disiez qu'un (ou le) coupable de l'erreur TS6059 est un fichier dans rootDir important quelque chose de l'extérieur rootDir bien que je pense vous avoir mal lu. Quoi qu'il en soit, je suis d'accord avec d'autres ici pour être surpris que les répertoires en dehors de rootDir doivent être explicitement exclus comme vous le décrivez.

Non, je disais (auparavant) que l'arbre de référence peut entraîner la transposition de choses dans votre liste d'exclusion - légèrement différente.

L'erreur TS6059 est un peu déconcertante au début - mais je la vois comme TS essayant de m'empêcher de faire des erreurs. Si je me suis donné la peine de définir un rootDir et que le dactylographié plonk vole en dehors de ce rootDir, alors TS dit effectivement "oi - vous avez créé un dactylographe auquel je ne peux pas accéder - n'est-ce pas?"

Soit je réponds "non, ce n'est pas bien, j'ai foiré" et je déplace les fichiers dans rootDir
OU
Je dis "oui c'est vrai et je suis désolé de ne pas vous avoir prévenu" - puis je l'ajoute à la liste des fichiers exclus.

C'est beaucoup trop compliqué. J'ai un monorepo et je n'arrive pas à trouver un moyen de compiler correctement chaque package pour lui-même, en émettant la bonne structure de répertoires, tout en important des packages locaux (à partir du même monorepo) à l'aide de l'option paths .

Soit la structure de répertoires dans le répertoire de sortie contient des dossiers parents indésirables, soit tsc se plaint que les fichiers se trouvent en dehors du répertoire racine.

Ça ne peut pas être si compliqué, non ?

Quelles que soient les options que j'utilise, quelle que soit la combinaison que j'utilise, tsc ne semble pas être capable de gérer un monorepo avec paths référençant des packages locaux dans le même monorepo. J'ai essayé --build , --project , references , paths , extends , rootDir , rootDirs , include , exclude , baseUrl , outDir dans toutes sortes de combinaisons avec des valeurs différentes et à la fin il se plaint que les fichiers ne se trouvent pas dans le rootDir ou il se trompe en émettant une mauvaise structure de répertoire à l'intérieur de outDir .

Je ne décrirais pas ce que j'ai comme un monorepo mais j'ai trois projets différents dans le même repo - et je peux transpiler chacun indépendamment sans problème ni interférence des autres. Chaque projet a son propre tsconfig

Après un certain temps à essayer et à bricoler, j'ai pu obtenir un monorepo avec lerna et dactylographié à exécuter. La configuration tapuscrit utilise references en combinaison avec paths et ne s'étouffe plus en utilisant rootDir .

le rootDir est utilisé pour construire la structure du dossier de sortie. tous les fichiers doivent être sous rootDir pour que le compilateur sache où écrire la sortie.

Qu'en est-il des fichiers qui ne nécessitent aucune sortie ? Avoir un fichier json en dehors de la racine :

const errors = require("../../../../errors.json");

Parce que je ne peux pas compiler la version ES6 :

import * as errors from "../../../../errors.json";

Cependant, avec la première version, je perds la sécurité de type.

@mhegazy Ce problème a été fermé il y a 3 ans. Cependant il semble que ce soit toujours une source de confusion 3 ans plus tard.

Pourriez-vous s'il vous plaît revoir ce statut « Fonctionnement comme prévu » ? Compte tenu de la réaction de la communauté dans ce fil, il est assez sûr de dire qu'il ne se comporte pas comme la communauté s'attend à ce qu'il se comporte . Qu'il s'agisse d'un problème de documentation, de renommer cette option, de modifier son comportement ou d'ajouter une nouvelle option, je pense qu'il y a en fait un élément d'action de votre côté à déterminer.

Je peux comprendre que vous ayez des priorités bien plus élevées que celle-ci, mais garder ce problème fermé sans aucun signe que les commentaires donnés ici ont déjà été évalués ne donne pas vraiment une très bonne image pour Typescript pour être honnête.

@ngryman Quelle est la prochaine étape ? rootDir a une définition - c'est la racine commune de mes fichiers source. Lorsqu'un fichier n'est pas dans cette racine commune, par la définition même de rootDir , c'est une erreur. Cette définition est documentée. Je ne peux rien faire contre le fait que les gens ont inventé leurs propres définitions pour rootDir et sont par la suite surpris.

C'est comme aller chez Starbucks et dire que demander un café au lait ne devrait pas donner lieu à un mélange d'espresso et de lait cuit à la vapeur. C'est inexploitable parce que vous vous disputez avec une définition . Si vous voulez une boisson différente, commandez autre chose. Si Starbucks n'offre pas le type de boisson que vous souhaitez, faites une suggestion sur ce que devrait être cette boisson et de quoi elle devrait être faite.

Comme je l'ai mentionné dans https://github.com/microsoft/TypeScript/issues/9858#issuecomment -370653478, je pense que la solution à ce problème est simplement une meilleure messagerie d'erreur. À l'époque où je l'ai rencontré et que j'ai finalement trouvé ce problème GitHub, ma plus grande frustration est venue du temps que j'ai perdu à essayer de comprendre le problème, puis à penser qu'il s'agissait d'un bogue du compilateur, puis à créer un cas de repro, puis à trouver un bug en double qui dit "fonctionne comme prévu". Échouer rapidement avec un message d'erreur clair m'aurait épargné tout cela.

S'il existe des fichiers source en dehors de rootDir cela signifie que le projet TypeScript est mal configuré. Je pense que donner à l'utilisateur un message clair indiquant cela ainsi que des conseils sur la façon de le résoudre résoudrait le problème pour beaucoup de gens.

@RyanCavanaugh Merci pour votre réponse rapide.

Si je vais sur cette page : https://www.typescriptlang.org/docs/handbook/compiler-options.html. J'ai lu la définition suivante :

Spécifie le répertoire racine des fichiers d'entrée. A utiliser uniquement pour contrôler la structure du répertoire de sortie avec --outDir.

Je comprends littéralement qu'il n'est " utilisé que pour contrôler la structure du répertoire de sortie" et c'est tout. La " seule utilisation " est importante ici. Comment pourrais-je même deviner que ce n'est pas la seule chose que le compilateur fait en réalité, mais qu'il émettra également des erreurs si j'ai des fichiers Typescript en dehors de ce répertoire.

Il me manque peut-être quelque chose, mais si c'est le cas, je suis loin d'être le seul. Donc si vous avez un produit, et qu'une bonne partie de vos utilisateurs ne comprennent pas votre produit, il n'y a que 2 chemins à prendre : soit vous considérez vos utilisateurs comme stupides, soit vous n'avez pas réussi à communiquer quelque chose clairement. J'espère que tu ne penches pas pour le premier 😕

Pour finir avec votre exemple Starbuck, écrivez bien "mélange d'expresso & lait cuit à la vapeur" dans la liste des ingrédients, pour que je sache ce qu'est un latte, et je n'ai pas à deviner.

L'implication d'un fichier en dehors du rootDir serait que TS produirait un fichier en dehors du outDir , ce qui, à mon avis, est un comportement manifestement mauvais.

Le message d'erreur pourrait être meilleur - j'aimerais une suggestion ou un PR pour cela.

Les documents pourraient toujours être meilleurs - encore une fois, j'adorerais des idées concrètes sur la façon de communiquer les choses plus clairement.

Insinuer que je traite les gens de stupides n'est plus quelque chose que j'aimerais.

L'implication d'un fichier en dehors du rootDir serait que TS produirait un fichier en dehors du outDir, ce qui, à mon avis, est un comportement manifestement mauvais.

Je ne comprends toujours pas très bien pourquoi le compilateur ne se contenterait pas de "chrooter" en rootDir et ne considérerait pas les fichiers en dehors de ce répertoire. En tant qu'utilisateur, manquant probablement de contexte sur les éléments internes et l'historique de tsc , ce n'est certainement pas un comportement prévisible pour moi.

Un exemple que je peux donner hors de ma tête est Jest qui offre la même option : https://jestjs.io/docs/en/configuration#rootdir -string. AFAIK Jest ne considère pas les fichiers de test en dehors de rootDir . Je m'attendrais au même comportement ici par exemple.

Les documents pourraient toujours être meilleurs - encore une fois, j'adorerais des idées concrètes sur la façon de communiquer les choses plus clairement.

Je suis heureux que vous envisagiez des améliorations ici. La suggestion de @MicahZoltu pourrait être intéressante à explorer.

De mon côté, je peux réaffirmer que je ne pense pas que rootDir soit prévisible (d'où la réaction des gens), mais si je comprends bien, changer le comportement de cette option n'est pas quelque chose à considérer. Donc, comme compromis, une chose que je pourrais également proposer serait de renommer rootDir en un nom plus significatif, outBaseDir pourrait être un candidat. Mais il y a probablement un meilleur nom.

Insinuer que je traite les gens de stupides n'est plus quelque chose que j'aimerais.

Je n'ai rien insinué et je suis désolé si vous l'avez pris de cette façon. Je n'ai énoncé qu'un fait très simple : lorsque les utilisateurs se plaignent de quelque chose qu'ils ne comprennent pas, il n'y a effectivement que 2 chemins à emprunter. J'en ai conclu que j'espère que vous ne pensiez pas au premier. Le fait que vous vous associez à l'un de ces chemins vous est honnêtement laissé à vous.

Je pense avoir dit ce que j'avais à dire, en particulier en donnant des commentaires francs sur la façon dont ce fil a été traité. Je vais donc laisser la place à d'autres pour proposer des solutions.

@ngryman Je suis d'accord pour dire que la définition de rootDir et ce qu'il fait réellement ne semblent pas correspondre. Lorsque vous créez un nouveau projet ts (via tsc --init ) le commentaire dans tsconfig.json pour rootDir est similaire à ce que vous avez cité /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ . Si je fournis un répertoire de fichiers _input_, je m'attends à ce que les seuls qu'il envisage même de compiler soient dans ce répertoire, par la définition de input.

@RyanCavanaugh Il peut avoir un sens pour signaler une erreur comme celui - ci il y a 4 ans quand tapuscrit a été utilisé uniquement pour être compilé en javascript. Bien sûr, je ne veux pas de fichiers manquants ! Mais maintenant, avec la popularité de l'exécution dactylographiée, comme ts-node , il semble que tsc soit un peu jaloux avec moi.

Et l'idée que les fichiers dactylographiés en dehors du rootDir impliquent une configuration de projet incorrecte est tout simplement fausse. Je n'ai pas besoin que mes tests unitaires, qui sont écrits en tapuscrit, soient compilés en javascript. ts-node est tout simplement plus rapide et je profite de tous les avantages du tapuscrit lors de la rédaction de tests.

Je suis d'accord avec @CodySchrank . Je suis d'accord avec l'erreur de TS lorsqu'un fichier source à l'intérieur de rootDir référence/importe un fichier en dehors de celui-ci - c'est normal.

Cependant, je ne peux pas comprendre que TypeScript par lui-même examine des fichiers non liés en dehors de rootDir et génère des erreurs alors qu'il s'agit simplement de fichiers de configuration pour différents outils, comme jest ou autre. Je veux dire, à quoi ça sert ? Ceux-ci ne font même pas partie de mon application et ne sont référencés/importés nulle part directement, et mon Dieu, pourquoi voudrais-je qu'ils soient regroupés dans la version résultante en premier lieu...

Je me demande quelles seraient les implications de transformer cette erreur en avertissement. Après avoir brièvement parcouru le code, cela semble certainement possible, mais je ne suis certainement pas un expert du processus de construction de tsc. Cela semble être un juste milieu entre nous tenir informés d'un problème potentiel mais aussi nous permettre de le contourner si nous le voulons.

La configuration src / test / out était un scénario clé abordé par les références du projet

Cela nécessite au moins une configuration de projet distincte pour chaque dossier racine (https://www.typescriptlang.org/docs/handbook/project-references.html). Après avoir lu les instructions, je suis reparti sans bien comprendre comment mettre en œuvre le modèle et j'ai l'impression qu'on me remet un marteau-piqueur alors que ce que j'ai demandé était une tapette à mouches.

Bien sûr, maintenir les modules annexes en tant que sous-projets séparés dans mon dossier source est plus efficace, mais je ne compile pas lodash ici. Ce que je veux, c'est inclure de nombreux fichiers, comme des fichiers de test et de référence, dans un dossier de projet commun pour l'analyse statique, et quand vient le temps de compiler, n'émettre qu'un seul répertoire pour une utilisation par le monde extérieur. Cela semble assez facile à spécifier et j'ai du mal à voir pourquoi c'est non seulement difficile à faire pour l'utilisateur, mais apparemment _verboten_ du point de vue de la spécification TS.

Ce que je veux souligner, c'est que la seule raison pour laquelle cette fonctionnalité est interdite est due à l'hypothèse du compilateur d'une intention de corruption de la part du développeur. Lorsque le développeur définit "outDir" sur ./src et que le compilateur trouve un fichier TS dans ./test , il _pourrait_ supposer que ce fichier n'a pas besoin d'être émis (en supposant bien sûr que il n'est référencé à partir d'aucun fichier dans "outDir").

Mais ce n'est pas le cas. Il suppose que le développeur _voulait_ émettre ce fichier, et par incompétence ou malice a spécifié un sous-répertoire qui ne le contient pas. En d'autres termes, le compilateur a la possibilité de faire correspondre les instructions du développeur à un cas d'utilisation courant et raisonnable, et à la place de les faire correspondre à quelque chose d'absurde et refuse de continuer.

Dans l'état actuel des choses, je ne vois même pas quel est le cas d'utilisation légitime de "outDir" . Je suppose que c'est pour prendre en charge une structure de projet où le tsconfig.json est au niveau supérieur avec d'autres fichiers de configuration et de métadonnées, et le propriétaire souhaite que le dossier compilé ne représente que le dossier source qui y est imbriqué. (Assurez-vous simplement qu'aucun de ces méta-fichiers ne se termine par .ts : ce serait absurde.)

Il me semble que la conception de la spécification est hostile à l'utilisateur. Il a été fait référence à la commande d'un verre chez Starbucks et au fait d'être contrarié alors que ce n'était pas ce à quoi vous vous attendiez, malgré les ingrédients figurant sur le menu. C'est tout à fait approprié, mais je comparerais davantage cette fonctionnalité à un stand de hot-dogs qui ne vend pas de hot-dogs.

Bien sûr, les clients irrités auraient dû revenir en arrière et voir le grand panneau proclamant hardiment que le stand de hot-dogs ne vendait pas de hot-dogs. Mais à mesure que la confusion s'accumule, les propriétaires du stand de hot-dogs pourraient avoir l'occasion de réfléchir à la façon dont ils communiquent les capacités de leur produit aux clients.

Hmm, en y réfléchissant davantage, je me demande s'il y a une sorte d'invariant de la part de l'équipe principale qui sous-tend ce problème :

Tout le code source doit être compilé. S'il n'est pas compilé, ce n'est pas du code source.

En pays utilisateur, il est nécessaire de surmonter cela d'une manière ou d'une autre. Je ne sais pas si nous le faisons en étendant la définition du code source, à savoir. TypeScript, ou en créant une seconde catégorie (« code support », « code de validation », « code périphérique »...). Ce serait du code qui devrait fonctionner sous les mêmes définitions de type que la source, et qui doit être validé avec succès pour que la source soit considérée comme correcte, mais qui ne fait pas partie de la fonctionnalité réelle du programme en ce qui concerne son interface.

En tant que consommateur de TypeScript, je ne comprends pas les difficultés spécifiques de la mise en œuvre d'une telle catégorie. Cependant, il semble que cela convienne parfaitement à "outDir" : tout ce qui se trouve à l'intérieur de "outDir" fait partie de la source, tout ce qui se trouve à l'extérieur mais à l'intérieur du dossier du projet fait partie du code de support. La principale chose qui rend cela utile/nécessaire est l'avènement de ts-node, ce qui signifie que je peux exécuter ce code de support en tant qu'étape distincte, complètement indépendante de la compilation ; et bien sûr je veux pouvoir en profiter.

n'inclut pas implicitement les fichiers d'entrée fournis à l'outil

Ce problème est causé exactement _parce que_ l'utilisateur essaie implicitement de compiler des fichiers en dehors du rootDir . En gros, vous avez dit au compilateur "ne compiler que les fichiers dans ce répertoire", puis vous avez commencé à référencer des fichiers en dehors de ce répertoire. Le compilateur est confus et ne sait pas comment procéder.


/project/source/index.ts

import '../external.ts'

/project/tsconfig.json

{
  "compilerOptions": {
    "rootDir": "./source"
  }
}

Dans cet exemple, vous indiquez au compilateur « les fichiers sources se trouvent uniquement dans le répertoire 'source' ». Ensuite, l'un de ces fichiers fait référence à un fichier qui n'est _pas_ dans le répertoire source. TypeScript a maintenant deux instructions contradictoires, l'une dit de compiler uniquement les fichiers dans le répertoire source, l'autre dit de compiler les fichiers en dehors du répertoire source.

@MattiasMartens, vous include et rootDir . Si vous avez /src et /test , si include est src/* alors vous ne pouvez pas obtenir d'erreurs sur des choses dans /test moins que quelque chose de src incorrectement importé quelque chose de test , ce dont vous devriez être heureux !

Il n'est pas hostile à l'utilisateur ou antagoniste de fournir un mécanisme pour noter à quoi ressemble une importation incorrecte dans votre programme et d'émettre une erreur lorsqu'une telle importation incorrecte se produit. Encore une fois , je pense que cela vient d'un lieu de malentendu ce que les drapeaux moyenne - ils sont principalement opt-in des


De toute façon!

Étant donné la définition de rootDir , lorsque TypeScript voit un fichier en dehors du rootDir fourni, il a quelques options :

  • Émettre un fichier au-dessus du outDir (en supposant que cela soit même possible !), ce qui contredit les instructions de l'utilisateur concernant l'emplacement de sortie
  • Traitez le fichier mais ne l'émettez pas, ce qui, en l'absence d'autres étapes de construction, produira un programme qui ne fonctionnera pas
  • Émettre une erreur car le projet semble être mal configuré

Je m'oppose fortement à l'idée qu'émettre un programme qui ne fonctionne pas devrait être la valeur par défaut. Si la demande de fonctionnalité ici est simplement de traiter les fichiers .ts trouvés en dehors de rootDir comme .d.ts , c'est raisonnable, c'est juste une chose distincte de rootDir signifiant autre chose que rootDir . Comment appelleriez-vous un tel drapeau ?

@MattiasMartens, vous include et rootDir . Si vous avez /src et /test , si include est src/* alors vous ne pouvez pas obtenir d'erreurs sur des choses dans /test moins que quelque chose de src incorrectement importé quelque chose de test , ce dont vous devriez être heureux !

C'est vrai. J'ai réfléchi avec include et j'ai trouvé que cela fonctionnait mieux que je ne le pensais pour ce cas, y compris avec l'outillage de VSCode.

J'aimerais toujours avoir du code validé à la compilation mais non émis à la compilation, ce que include ne couvre pas. Mais c'est une demande distincte qui n'a pas besoin d'être discutée ici.

Je pense que cela vient d'un malentendu sur ce que les drapeaux _signifient_ - ce sont principalement des _contrôles d'application opt-in_ pour vous aider à valider que votre programme est correctement configuré.

Je suis confus par cela. Considérez-vous rootDir un contrôle d'application opt-in ? Cela affecte ce qui est finalement émis, il ne s'agit donc clairement pas _seulement_ d'un contrôle d'exécution.

Certains indicateurs, comme target , modifient radicalement ce qui sera émis -- ce ne sont pas des contrôles d'application mais des instructions du compilateur. rootDir lit comme, et est documenté comme, une instruction du compilateur.

Je m'oppose fortement à l'idée que _émettre un programme qui ne fonctionne pas_ devrait être la valeur par défaut.

D'après ce que j'ai lu de ce fil jusqu'à présent, il semble y avoir un large consensus sur le fait qu'une référence d'un fichier à l' intérieur de rootDir à un fichier à l' extérieur de rootDir _devrait être une erreur_. L'aspect de la fonctionnalité que moi et d'autres avons trouvé frustrant, c'est qu'elle ne s'arrête pas là, mais génère en fait une erreur si elle trouve des fichiers TS dans le dossier du projet en dehors de rootDir qu'il s'agisse d'un fichier dans rootDir importe ou non.

Cela mérite d'être répété : j'ai mis rootDir dans le dossier où réside mon code source, le compilateur remarque un autre code TS dans le projet qui n'a rien à voir avec ce qu'il y a dans rootDir , et il s'arrête ! Ce comportement spécifique ne m'aide pas à comprendre mon code. C'est tout simplement agaçant.

Il est vrai que du point de vue de la définition TypeScript de rootDir , telle qu'elle est élaborée dans ce fil, le comportement est parfaitement raisonnable, et tous ceux qui sont venus ici pour exprimer leur frustration à ce sujet sont dans l'erreur. Mais ce n'est pas raisonnable d'après la définition conventionnelle attendue d'un répertoire racine. Je vous dis que dans pratiquement tous les contextes où je fournis un répertoire racine, je dis au programme par où commencer à parcourir la structure du fichier, sans lui demander s'il est absolument sûr qu'il n'y a pas autre chose dans le système de fichiers que je pourrais aussi être intéressé par.

Les définitions peuvent être fausses. Ils peuvent être modifiés. Pour une compatibilité descendante, il n'est pas nécessaire de conserver des définitions, seulement des fonctionnalités.

Si la demande de fonctionnalité ici est simplement de traiter les fichiers .ts trouvés en dehors du rootDir comme .d.ts

Je... ne pense pas que je le veuille, pour à peu près les mêmes raisons que je veux que le compilateur renvoie une erreur lorsque quelque chose dans rootDir importe du code de l'extérieur. Je pense que le contenu d'un rootDir si j'en fournis un devrait être encapsulé à partir du code environnant.

Je pense que le moyen le plus simple d'éviter le comportement que moi et d'autres ne voulons pas est d'exclure implicitement les fichiers en dehors de rootDir si les fichiers dans rootDir n'y font pas référence. Si les fichiers de rootDir font référence, une erreur devrait être renvoyée, comme c'est le cas actuellement.

Chaque paragraphe semble se résumer à " rootDir devrait changer la valeur par défaut de include ", ce qui serait une chose raisonnable à suggérer si nous ajoutions ces drapeaux aujourd'hui en même temps, mais n'est pas un changement révolutionnaire que nous pourrions faire pour le moment. Bien que sans doute faire tous les drapeaux de configuration interagissent les uns avec les autres plus augmente la charge cognitive plutôt que diminuer.

Peut-être devrions-nous simplement émettre une erreur personnalisée lorsque include n'est pas explicitement défini et qu'un fichier inclus est en dehors de rootDir .

Le fichier "tests/foo.ts" est en dehors de rootDir 'src'. Avez-vous oublié de définir un modèle « include » ?

Connecté #33515

J'ai eu des problèmes avec cela, également sur https://github.com/microsoft/TypeScript/issues/31757#event -2480427393

L'interaction entre rootDir, inclure et exclure est simplement conçue de manière si étrange.

J'ai toujours pensé que rootDir est le dossier que le compilateur commence à parcourir et qu'il inclut des dossiers supplémentaires (par exemple des dossiers de fournisseurs) qui pourraient être référencés à partir de rootDir.

La définition actuelle est étrange comme l'enfer et extrêmement peu intuitive.

Ironiquement, ce qui est déroutant, c'est qu'ils n'interagissent pas : les paramètres ne s'affectent pas du tout. include contrôle à 100% le contenu du programme et rootDir contrôle à 100% le calcul de la disposition de outDir .

Juste pour ajouter un autre exemple du problème, voici ma structure de dossier :

tsconfig.json
package.json
src/index.ts

J'ai dans mon tsconfig :

"rootDir": "src",
"outDir": "lib",

Et dans mon "index.ts" (dossier src)

import pkg from '../package.json'; // I read the package.json object

export class SomeClass {
  public version = pkg.version;
}

Je _sais_ qu'après la construction, le fichier "index.js" sera dans le dossier "lib". Et je _sais_ que le package.json sera 1 niveau supérieur.
Je ne pense pas que Typescript devrait mieux connaître que moi ma structure de dossiers et casser la construction. Il devrait simplement enregistrer un avertissement concernant certains fichiers en dehors du dossier rootDir qui n'étaient pas inclus dans le dossier de sortie.

@sebelga Je considérerais probablement qu'un bogue - autoriser .json de l'extérieur rootDir serait OK puisque TS ne le copie pas dans le dossier de sortie

@sebelga Je considérerais probablement qu'un bogue - autoriser .json depuis l'extérieur de rootDir serait OK puisque TS ne le copie pas dans le dossier de sortie

Merci, ce n'est pas vrai.. Nous avons des règles spéciales pour émettre des fichiers .json... Si le fichier doit être émis au même endroit, alors seulement il n'est pas émis. Dans tous les cas, il est émis (par exemple, lorsque --outDir est spécifié, il sera émis dans ce dossier)

@RyanCavanaugh J'ai un cas d'utilisation similaire à @sebelga où je veux console.log le numéro de version de package.json au moment de l'exécution.

Donc ma solution était de changer mon "rootDir": "." , alors j'ai ceci comprend

"include": [
    "src",
    "typings"
  ]

Et comme le fichier package.json est inclus dans le dossier lib (construit), qui contient un sous-dossier "src", j'ai écrit un script bash qui s'exécute juste après la construction pour nettoyer les choses.

#!/bin/bash

rm lib/package.json
mv $(pwd)/lib/src/* $(pwd)/lib
rm -rf lib/src

Cela fonctionne, mais me semble assez hacky.

@sebelga Avez-vous des fichiers .ts dans le dossier typings ? Sinon, il serait légal de définir rootDir sur src et de sauter le script.

@sebelga Au lieu de const { version } require('../../package.json') ou import { version } from 'package.json') , avez-vous essayé de faire quelque chose comme ceci :

import { sync as loadJsonFileSync } from 'load-json-file';

const { version } = loadJsonFileSync('../../package.json');

TypeScript ne se souciera pas qu'il soit en dehors du rootDir cette façon.

https://github.com/sindresorhus/load-json-file

Si vous voulez éviter de coder en dur tous les ../.. vous pouvez essayer ceci :
https://github.com/sindresorhus/read-pkg-up

@RyanCavanaugh Je ne peux pas le définir sur "src" comme mentionné ci-dessus. J'importe "package.json" en dehors de notre src ( import pkg from '../package.json'; ) et tsc ne le permet pas.

Merci pour ce partage @dylang ! Je vais essayer.

J'ai dit à dactylographié que ma source était toute dans un dossier particulier (via rootDir)

Ce n'est pas ce que signifie rootDir ! rootDir signifie "Utiliser ce dossier comme base relative pour calculer les chemins dans outDir ". _Quels fichiers font partie de votre compilation_ est une question distincte à laquelle répond files et/ou include / exclude

@RyanCavanaugh Mais c'est ce que rootDir devrait signifier, et c'est le sujet de ce problème.

Je ne suis pas très doué pour garder mon sang-froid lorsque je vois des problèmes ouverts depuis 2016 qui pourraient probablement être très résolus sans introduire de nouveaux problèmes pour les utilisateurs existants en introduisant une nouvelle "option de compilation" pour informer le compilateur qu'il peut ignorer l'erreur dans un cas d'utilisation donné.

Pour cela, je m'excuse. Je n'y peux rien, car on compte sur moi pour fournir un bon service, mais je rencontre parfois des problèmes comme ceux-ci. Pourquoi est-il si difficile pour les auteurs de TypeScript d'implémenter un seul indicateur de configuration ?

Je ne pense pas que ce soit parce que les développeurs sont paresseux ou parce qu'ils ne veulent pas aider. Je ne pense pas que quiconque ici soit une mauvaise personne, à part moi-même.

C'est ce conflit, ce débat, qui dure depuis des années sur ce qui semble être la définition de la propriété "rootDir". Et que faire à propos de ce problème.

Les gens sont jetés dans ce débat parce qu'ils croient qu'ils ont raison. Oui, "rootDir" sert de répertoire de base pour le code source. Oui, l'erreur est valide.

Pourtant, le problème sous-jacent persiste. Mon outillage compile parfaitement le code, pourtant mon IDE affiche cette erreur sur mon écran. C'est une perversion. Je veux que ces lignes rouges disparaissent. Mes fichiers ne contiennent pas d'erreurs. Et s'ils le font, je devrais me concentrer sur ceux-ci plutôt que d'être distrait par ces non-problèmes.

Tout ce que je veux, c'est supprimer ce message d'erreur. Je pense que c'est ce que la plupart d'entre nous veulent. Je ne sais pas s'il y a d'autres cas ici et peut-être qu'il y a des gens qui aimeraient en parler.

Pouvons-nous s'il vous plaît travailler ensemble et résoudre ce problème? Ça me ferait tellement plaisir de voir ces lignes rouges disparaître...

@nullquery Si tsc fonctionne mais que votre IDE affiche vos squigglies rouges, cela signifie que votre IDE n'utilise pas la même version ou configuration du compilateur que tsc .

@nullquery fichier un bogue qui montre comment reproduire le problème et nous allons le résoudre ou vous dire ce qui ne va pas avec la configuration de votre projet

Suite à la solution de contournement @sebelga , voici une variante qui convient pour entrer dans vos scripts npm

tsc --module commonjs --target ESNext --outDir ./edition-esnext --project tsconfig.json && test -d edition-esnext/source && ( mv edition-esnext/source edition-temp && rm -Rf edition-esnext && mv edition-temp edition-esnext ) || true

Exemple d'utilisation ici.

Boundation l'appliquera automatiquement pour vous.

La solution est Références de projet .

Pour l'utiliser, éditez votre fichier "tsconfig.json" et ajoutez-le à la fin du fichier (en dehors des "compilerOptions") :

"references": [
    { "path": "../common" }
]

Cela vous permettra de référencer des fichiers dans le dossier "../common/" (et tous les sous-dossiers).


Ma confusion précédente provenait du fait qu'IntelliJ et ma tâche gulp-typescript corrompue me donnaient des résultats différents malgré l'utilisation du même fichier "tsconfig.json".

Il s'avère que pour une raison quelconque, "gulp-typescript" essaie une approche de compilation au mieux.

Une erreur dans TypeScript (telle que let z: number = '' ) sera signalée dans IntelliJ mais "gulp-typescript" la compile très bien.
Seules les erreurs de syntaxe JavaScript (telles que let 1z = '' ) sont signalées par "gulp-typescript".

Donc, si vous êtes un utilisateur de "gulp-typescript", vous pouvez rencontrer un tel problème en fonction de votre version de "gulp-typescript" et de votre configuration. (J'utilise la dernière version au moment de la rédaction, mais je suppose que quelqu'un du futur pourrait lire ceci. J'espère que les temps sont meilleurs pour vous.)


Je sais que l'utilisation de Project References est enfouie quelque part dans cette avalanche de réponses, mais cela aurait été mieux si cela avait été mieux documenté.

Les 3 premiers résultats pour "TS6059" sur Google conduisent tous à des problèmes GitHub. Cela aurait été beaucoup plus clair pour moi s'il y avait eu une page documentant ces erreurs courantes et leurs solutions.

@MicahZoltu Est-ce quelque chose qui peut être résolu ? Dois-je faire un nouveau numéro, ou est-ce quelque chose qui irait plus vite s'il était discuté en interne entre les principaux contributeurs ?

(FWIW je ne fais pas partie de l'équipe TypeScript)

En règle générale, je déconseille d'utiliser path s à moins que vous n'y soyez absolument obligé. Je pense que son objectif est de permettre la compatibilité avec les projets JS hérités avec des structures de dépendance étranges, mais je ne pense pas qu'il soit destiné à être utilisé sur de nouveaux projets, et si vous en avez besoin, vous pouvez envisager de migrer à partir de celui-ci lorsque vous avez l'opportunité. Je ne l'utilise pas personnellement, donc je ne peux pas vraiment vous aider avec les problèmes que vous pourriez avoir, mais j'ai vu beaucoup de gens se débattre avec et la solution est généralement de "arrêter de l'utiliser".

En ce qui concerne gulp-typescript, il semble que la version de TSC utilisée par gulp-typescript soit peut-être différente de la version de TSC utilisée par IntelliJ. Lorsque vous voyez des symptômes comme vous les décrivez, c'est généralement le problème (l'autre étant qu'ils n'utilisent pas le même tsconfig.json ).

La version utilisée par "gulp-typescript" doit être identique ; les deux versions sont dérivées de node_modules . J'ai essayé différentes manières de détecter les erreurs et de modifier les paramètres qui s'y rapportent (y compris en jouant avec les différents "reporters" fournis par "gulp-typescript" et en essayant de remplacer les paramètres pour émettre plus d'erreurs. Rien ne semble fonctionner.

C'est bien quand même. Tant qu'IntelliJ me donne des erreurs, je suis heureux d'accepter que la tâche Gulp les ignore.


Je ne suis pas fan de la refonte de ma méthode au profit de la méthode préférée de la semaine. La structure de projet que j'ai a du sens pour moi. Il garde tout contenu tout en me donnant la possibilité de diviser les choses en plusieurs composants.

Je ne crois pas à « autoriser la compatibilité pour des raisons héritées », et surtout lorsqu'il s'agit de références de projet. Il _doit_ être possible de référencer des fichiers en dehors du rootDir ou vous n'aurez tout simplement pas la liberté de définir la structure du projet d'une manière qui ait du sens pour vous et votre équipe.


Lorsque j'ai commencé à travailler avec TypeScript, j'ai rencontré de nombreux problèmes. Parmi eux:

  • Pour inclure des fichiers JavaScript, la solution idéale semblait être AMD à l'époque. Le site Web avait l'air officiel et il y avait de nombreux exemples en ligne d'AMD en production. Mais apparemment, Webpack était la nouvelle grande nouveauté et donc certains projets ne fonctionnaient tout simplement pas dans un environnement AMD. Leçon apprise : tout le monde n'adoptera pas la nouvelle méthode, vous êtes donc toujours foutu.

  • La route de TypeScript au JavaScript minifié finalisé (avec mappages de sources) n'était pas claire pour moi. Plusieurs méthodes différentes étaient disponibles à l'époque, mais aucune ne semblait fonctionner nativement avec les fichiers "tsconfig.json" et/ou mon IDE à l'époque. Leçon apprise : si vous voulez que quelque chose soit bien fait, vous devez le faire vous-même ; ne comptez pas sur les autres pour faire le travail à votre place, peu importe à quel point ils sont bien intentionnés, personne n'est parfait et personne ne peut prédire _votre_ espace de travail.

  • Il y avait une chose personnalisée que je voulais : un moyen de convertir le contenu des fichiers HTML en un dictionnaire JavaScript pour l'inclusion. Cela aurait dû être ma seule pierre d'achoppement, mais au final, cela s'est avéré être l'un des scripts les plus faciles à écrire.

J'ai fini par devoir développer mon propre Gulpfile pour tout gérer. Il effectue les opérations suivantes :

  • Copie les fichiers JavaScript minifiés pour distribution à partir du dossier node_modules vers ma racine Web. Cela semble simple, mais presque toutes les bibliothèques JavaScript que j'ai essayé d'inclure avaient un endroit différent où elles stockaient leurs fichiers JavaScript minifiés. Il n'y avait pas de configuration, pas de chemin clair vers les fichiers. J'ai fini par devoir écrire des scripts séparés pour chaque bibliothèque JavaScript que je voulais inclure. Cela fonctionne, en supposant que l'emplacement ne change pas dans les versions futures, mais si c'est le cas, je peux toujours modifier le script de copie.

  • Compile TypeScript en fonction du fichier local "tsconfig.json" qui génère des fichiers séparés dans un répertoire de sortie (en utilisant outDir ) afin que je puisse être sûr que TypeScript est compilé de la même manière dans mon IDE que dans Gulp (hahahahaha !), puis utilise le plug-in "rollup" pour compresser ces fichiers en un seul fichier JavaScript, puis exécute UglifyJS pour réduire ce fichier, tout en conservant un mappage source qui renvoie au fichier TypeScript d'origine.

  • (Tâche personnalisée) Génère un fichier JavaScript contenant un dictionnaire appelé html_templates pour chaque fichier HTML dans la racine source TypeScript et le place dans mon dossier racine Web en tant que fichier JavaScript minifié.

Il existe peut-être des solutions plus élégantes, mais après être passé d'un projet open source à l'autre, j'en ai eu assez de jongler entre les solutions que chacun offrait.

L'approche que j'ai choisie fonctionne, elle est assez simple à comprendre (surtout maintenant que je comprends que "gulp-typescript" fait quelque chose de différent) et je continuerai probablement à l'utiliser pendant des années.

La meilleure solution est celle que vous comprenez vous-même. Bien que cela n'aide personne qui essaie de m'aider (ce que j'apprécie beaucoup ! l'aide je veux dire, pas la confusion), je peux dire par expérience qu'il y aura toujours quelque chose qui ne va pas avec _n'importe quelle_ solution, il est donc préférable de s'en tenir à quelque chose vous possédez vous-même que quelque chose qui est conçu, développé et produit par une équipe multiculturelle de diverses croyances, orientations sexuelles et identités de genre .


tl; dr s'il vous plaît ne cassez pas les références du projet. J'en ai besoin pour que mon outillage fonctionne. Merci

J'ai abandonné la configuration de la configuration TS multi-projets et je fais simplement tsc -w dans chaque projet et npm link , puis vous pouvez simplement ignorer toutes les complexités de tsconfig multi-projets et simplement vous référer à d'autres projet comme s'il s'agissait de dépendances simples de node.js dans node_modules .

Mais aujourd'hui, dans un projet, j'ai changé la cible de es5 à es6 et elle ne compilera plus car File '.../lib.ts' is not under 'rootDir' .

Structure du fichier :

/app
 - tsconfig.json // rootDir = "."
 - app.ts (

/app/node_modules/lib
 - tsconfig.json // rootDir = "."
 - lib.ts
 - lib.js
 - lib.d.ts

Pourquoi tsc dans /app soucie du fichier /app/node_modules/lib/lib.ts ? Il ne devrait pas du tout utiliser ce fichier. Il y a compilé /app/node_modules/lib/lib.js et /app/node_modules/lib/lib.d.ts .

Si /app/node_modules/lib/lib.ts supprimé - surprise - il se compile bien.

@alexeypetrushin vous pouvez jeter un œil à certains de mes projets. Cela semble bien fonctionner. par exemple:

import * as pkg from '../package.json';

NAN. Et il n'y a aucun moyen de désactiver cette erreur que je peux trouver.

@SephReed : J'ai dépensé 200 points de représentation sur StackOverflow et quelqu'un a contribué à cette solution très simple pour importer ../package.json . Tout ce que vous avez à faire est de placer un fichier typings.d.ts dans le même répertoire que package.json , avec ce contenu :

declare module '*.json';

Je n'ai aucune idée de comment cela fonctionne, mais honnêtement, je m'en fiche. À ce stade, TS se forçait pour lui-même, pas pour moi.

Je suis surpris que ce débat soit si houleux. Mais je comprends le raisonnement. Pour moi, j'ai bien sûr le dossier source, mais j'ai aussi des scripts de construction en dehors de ce dossier qui ne sont pas destinés à être compilés mais incluent définitivement la prise en charge des types, car soyons honnêtes, votre meilleur IntelliSense est TypeScript.

repo/
⊢ config/  << provide TS support, but don't build this directory
  ⨽ webpack.config.ts 
⊢ scripts/  << provide TS support, but don't build this directory
  ⨽ release.ts
⊢ src/        << build this directory
  ⨽ example.ts
⨽ tsconfig.json

J'utilise donc "rootDir": "src" pour m'assurer que les fichiers sont dirigés vers dist et non dist/src . Mais bien sûr, TypeScript aime se plaindre de cette configuration, mais depuis que j'utilise Webpack, il n'y a pas d'erreur pour moi.

J'ai enfin compris ce que signifie exactement ce drapeau sans plusieurs commentaires qui ne le rendent pas plus clair. Bravo avec ça.

Les options qui définissent les dossiers et fichiers pour que tsc prenne en compte la conformité : "files", "include", "exclude".

Alors pourquoi utilisez-vous "rootDir" ?
rootDir est la racine de la structure de répertoires (hiérarchie) de vos fichiers source, que tsc utilise pour émettre la même structure de répertoires à partir du répertoire tsconfig.json ou "outDir" s'il est spécifié. Ce n'est donc pas le chemin que tsc utilise comme chemin de base pour "outDir". "outDir" n'est que la racine que tsc émet des fichiers de sortie.
Par exemple, disons que votre projet Java a cette structure de répertoires.

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

Lorsque vous définissez "include" et "rootDir" comme ci-dessous, tsc générera la sortie sous la forme :

"include": "src/main/resources/static/ts" *
"rootDir": "." *

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.js *
          test.ts

Lorsque vous définissez également "outDir" comme ci-dessous, tsc générera la sortie sous la forme :

"include": "src/main/resources/static/ts"
"rootDir": "."
"outDir": "build" *

- build
  - src
    - main
      - resources
        - static
          - ts
            test.js *
- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

Vous vouliez probablement avoir cela en définissant l'option "rootDir" et en modifiant l'option "outDir" comme ci-dessous.

"include": "src/main/resources/static/ts"
"rootDir": "src/main/resources/static/ts" *
"outDir": "src/main/resources/static/js" *

- src
  - main
    - java
    - resources
      - static
        - js
          test.js *
        - ts
          test.ts

Ainsi, lorsque vous avez défini l'option "rootDir" qui ne couvre pas les portées des fichiers à l'exception de l'option "exclude", tsc ne parvient pas à se construire car cela n'a pas de sens avec le but de l'option "rootDir".

Ouais, c'est complètement une mauvaise pratique de nommage. Cela aurait dû être juste "rootOfStructureOfInputs" ou quelque chose. Et aussi, "outDir" aurait dû être simplement "rootOfOutputs".

Ce que vous voyez sur le SS n'est pas un problème WebStorm - il vient de TS DevServer.
La deuxième importation recommandée est la merde. Il récupère dans le dossier source "communication". Je ne sais pas qui diable devrait vouloir ça. Compiler un fichier avec une telle importation pose un tas de problèmes.

J'ai aussi essayé :

"exclude": ["lib", "node_modules",
        "..", "../..", "../../..", "../../../..", "../../../../..", "../../../../../.."
    ]

n'a pas résolu le problème non plus

Bildschirmfoto 2020-07-22 um 10 08 28

@mhegazy Vous avez étiqueté ce problème avec "Travailler comme prévu", mais ce n'est pas vrai. Comme vous pouvez le voir dans ma capture d'écran, tsc-server fournit des fichiers en dehors de mon rootDir (dans ce cas mobiservice/src) comme suggestion d'importation. Pour moi, cela ressemble à un bug...

Cette page vous a été utile?
0 / 5 - 0 notes