Tslint: no-implicit-dependencies : prise en charge du mappage des chemins

Créé le 20 oct. 2017  ·  18Commentaires  ·  Source: palantir/tslint

Rapport d'erreur

  • __TSLint version__ : 5.8.0
  • __TypeScript version__ : 2.7.0-dev.20171020
  • __Exécution de TSLint via__ : CLI

Code TypeScript en train d'être lint

src/a.ts

import { x } from "foo";

types/aliments.d.ts

export const x = 0;

tsconfig.json

{
    "compilerOptions": {
        "paths": {
            "*": "types/*"
        }
    }
}

avec la configuration tslint.json :

{
    "rules": {
        "no-implicit-dependencies": true
    }
}

Comportement réel

ERROR: /home/andy/sample/tslint/src/a.ts[1, 19]: Module 'foo' is not listed as dependency in package.json

Comportement prévisible

Pas d'erreur. Je pense que si une importation n'est pas résolue en quelque chose dans node_modules cette règle devrait l'ignorer.

Commentaire le plus utile

Cette règle ne fonctionne pas lorsque nous utilisons un alias pour notre propre code source (ne pas importer à partir de packages npm). Il est très utile d'utiliser un chemin absolu au lieu d'un chemin relatif.
Dans notre tsconfig.json, pour une application anguleuse, il suffit d'ajouter :

"compilerOptions": {
  ...
  "baseUrl": "./src",
  "paths": {
    "~/env": ["environments/environment"],
    "~/*": ["app/*"]
  }
}

Ensuite, nous pouvons faire des importations comme :

import {FooService} from '~/core';
import {Environment} from '~/env';

Peut-être devrions-nous rouvrir ce problème pour résoudre ce cas (il n'y a pas besoin de node_modules, juste le fichier tsconfig.json).
J'apprécie cette règle, il sera donc dommage de la désactiver.

Tous les 18 commentaires

Je pense que si une importation n'est pas résolue en quelque chose dans node_modules, cette règle devrait l'ignorer.

La règle n'essaie pas de résoudre les modules. Cela signifierait que vous devez avoir toutes les dépendances installées, ce qui n'est pas vraiment possible avec peerDependencies et optionalDependencies. Avec l'implémentation actuelle, vous pouvez pelucher un nouveau clone sans rien installer. Je suppose que c'est ce que font la plupart des outils de qualité de code.

Si je comprends bien les mappages de chemins, ils n'existent qu'au moment de la compilation. Au moment de l'exécution, vous avez toujours besoin du module installé pour node/webpack/whatever pour le récupérer correctement.
Cela signifie que les mappages de chemin ne sont pertinents que si vous avez des importations de type uniquement qui sont élidés lors de la compilation. Dans ce cas, la règle n'est probablement pas le bon choix pour vous.

Dans notre cas, il n'y a généralement pas de package.json , donc je suppose que nous devrions simplement désactiver cette règle alors. Merci!

Dans mon cas, j'"importe" des projets dactylographiés séparés sur lesquels je travaille simultanément en utilisant le mappage de chemin :

"compilerOptions": {
    ...
    "paths": {
        "tsbase": ["../tsBaseProject/src"],
        "tslibrary": ["../tsProjectLibrary/src"]
    }
}

pour que je puisse les utiliser dans le projet comme s'il s'agissait de modules.
Existe-t-il un moyen de les ajouter à la liste blanche ?

Les mappages de chemin dependencies ou peerDependencies à votre package.json

Lorsque je compile la source principale qui "importe" les projets secondaires, tout est compilé en un seul paquet comme s'il s'agissait de véritables dossiers du projet. Je n'ai pas besoin de les avoir dans le dossier node_modules.
Pour être clair, dans les dossiers de projet secondaires, j'ai des fichiers .ts réels, pas seulement les déclarations de type.

+1 pour l'ajout d'une liste blanche comme dans no-submodule-imports

Nous avons également le cas où nous utilisons le cas où nous définissons un alias de chemin '~' vers le répertoire de base afin d'éviter les importations relatives. Cet alias est plus tard résolu par webpack, fuse-box, etc. À partir de la 5.8, tslint crache beaucoup d'erreurs parasites à cause de cela...

Ce qu'il a dit ^^

Après la mise à niveau, j'ai maintenant des centaines de ces erreurs pour les mêmes raisons décrites ci-dessus. Une sorte de règle inutile.

Cette règle ne fonctionne pas lorsque nous utilisons un alias pour notre propre code source (ne pas importer à partir de packages npm). Il est très utile d'utiliser un chemin absolu au lieu d'un chemin relatif.
Dans notre tsconfig.json, pour une application anguleuse, il suffit d'ajouter :

"compilerOptions": {
  ...
  "baseUrl": "./src",
  "paths": {
    "~/env": ["environments/environment"],
    "~/*": ["app/*"]
  }
}

Ensuite, nous pouvons faire des importations comme :

import {FooService} from '~/core';
import {Environment} from '~/env';

Peut-être devrions-nous rouvrir ce problème pour résoudre ce cas (il n'y a pas besoin de node_modules, juste le fichier tsconfig.json).
J'apprécie cette règle, il sera donc dommage de la désactiver.

@andy-ms, veuillez reconsidérer les chemins de prise en charge (nous l'utilisons largement avec les espaces de travail nx). C'est une règle très utile, mais pour l'instant je suis obligé de la désactiver.

J'ai essayé de parcourir le code source et le correctif devrait aller quelque part le long de ces lignes . J'ai également vérifié comment Typescript gère cela et je l'ai suivi jusqu'à cette fonction . Il n'est certainement pas facile de reproduire cette logique. Je ne sais pas si cette fonction peut être réutilisée, il y a un tas d'arguments dont je ne suis pas certain.

J'aimerais beaucoup que cela soit réglé aussi. La cartographie des chemins est une fonctionnalité très appréciée. J'ai également essayé d'utiliser des modules liés comme solution de contournement, mais ceux-ci ne sont pas non plus pris en charge.

J'ai trouvé une solution de contournement qui résout quelque peu le problème pour moi, mais il n'est pas certain que ce soit le cas pour tout le monde, ou qu'il soit pas du tout maintenable. Quoi qu'il en soit, la solution est la suivante :

Ajoutez un faux paquet à optionalDependencies avec le nom de la carte de chemin de tsconfig.json , et installez les dépendances en utilisant npm install --no-optional . Cela ne fonctionne malheureusement pas avec yarn --ignore-optional - il n'arrive toujours pas à récupérer le paquet.

Donc, avec des chemins dans tsconfig.json ressemblant à ceci :

    "paths": {
        "~/*": ["src/*"],
        "some-path/*": ["whatever/*"]
    }

Et facultatif dans package.json comme ceci :

    "optionalDependencies": {
        "~": "tslint-hack",
        "some-path": "tslint-hack"
    },

Il devrait être possible d'installer les dépendances de production et de développement à l'aide de npm install --no-optional . Cela suppose évidemment que vous n'avez pas besoin d'installer de dépendances facultatives. Il convient également de mentionner que je ne l'ai pas fait fonctionner avec @ comme nom de package.

Si vous choisissez d'utiliser ce hack, est-il probablement judicieux d'ajouter un fichier .npmrc à la racine du projet, avec optional=false configuré, afin que vous puissiez recommencer à exécuter npm install sans le drapeau --no-optional .

Une autre solution qui _devrait_ fonctionner consiste à créer un package avec le nom souhaité et à le publier dans un registre privé, en utilisant verdaccio ou similaire. Je pense qu'il est possible de configurer des registres privés par module en utilisant .npmrc ou .yarnrc , et en tant que tel devrait être meilleur en termes de maintenabilité. Rien de tout cela n'est testé cependant.

J'espère que cela pourra aider un peu ceux qui souhaitent utiliser cette règle tslint et garder leurs résolutions de module en place. Mais cela ne remplace pas une solution appropriée.

Ayant également ce problème, le sonar signale cela de manière incorrecte comme une odeur de code.

Je pense qu'il s'agit d'une demande valide car tslint concerne uniquement le dactylographe et les chemins sont un paramètre dactylographié valide (et important).

Que faire si j'ai le package.json dans un répertoire différent de celui de tslint.json ?

- web
    - package.json
    - ClientApp
        - tslint.json

Je travaille sur une configuration similaire et j'obtiens des erreurs dans presque tous les fichiers en raison de cette règle. Une solution pour cela ?

La façon dont j'ai trouvé pour contourner ce problème utilise l'option de configuration suivante.

"no-implicit-dependencies": [true, ["src", "app", "~"]]

Il met en liste blanche les chemins fournis. Évidemment, cela signifie une duplication, mais c'est une solution rapide si vous en cherchez une.

Pour ceux d'entre nous qui utilisent des symboles @ comme préfixes pour les chemins personnalisés, j'ai créé un PR pour corriger un petit bogue avec l'implémentation actuelle #4192

"no-implicit-dependencies": [true, ["@src", "@app", "~"]]

@ifiokjr J'utilisais @ comme alias src, donc mes importations ressemblaient à @/components
Impossible de définir @ comme chemin ignoré car il a essayé d'importer @/components tant que module entier au lieu de résoudre d'abord @ .

J'ai changé mon alias en ~ et utilisé la ligne ci-dessus dans mon tslint, résolvant le problème

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