web-dev-qa-db-fra.com

Comment éviter les importations avec des chemins relatifs très longs dans Angular 2?

Comment puis-je introduire quelque chose comme 'my-app-name/services' pour éviter les lignes comme l'importation suivante?

import {XyService} from '../../../services/validation/xy.service';
80
Thomas Zuberbühler

TypeScript 2.0+

Dans TypeScript 2.0, vous pouvez ajouter une propriété baseUrl dans tsconfig.json:

{
    "compilerOptions": {
        "baseUrl": "."
        // etc...
    },
    // etc...
}

Ensuite, vous pouvez tout importer comme si vous étiez dans le répertoire de base:

import {XyService} from "services/validation/xy.service";

En plus de cela, vous pouvez ajouter une propriété paths, qui vous permet de faire correspondre un modèle, puis de le mapper. Par exemple:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "services/*": [
                "services/validation/*"
            ]
        }
        // etc...
    },
    // etc...
}

Ce qui vous permettrait de l'importer de n'importe où, comme ceci:

import {XyService} from "services/xy.service";

À partir de là, vous devrez configurer le chargeur de module que vous utilisez pour prendre en charge ces noms d'importation. À l'heure actuelle, le compilateur TypeScript ne semble pas les cartographier automatiquement.

Vous pouvez en savoir plus à ce sujet dans le problème de github . Il existe également une propriété rootDirs qui est utile lorsque vous utilisez plusieurs projets.

Pre TypeScript 2.0 (toujours applicable dans TS 2.0+)

J'ai trouvé que cela pouvait être facilité en utilisant "barrels" .

  1. Dans chaque dossier, créez un fichier index.ts.
  2. Dans ces fichiers, réexportez chaque fichier du dossier.

Exemple

Dans votre cas, commencez par créer un fichier appelé my-app-name/services/validation/index.ts. Dans ce fichier, avoir le code:

export * from "./xy.service";

Ensuite, créez un fichier appelé my-app-name/services/index.ts et obtenez ce code:

export * from "./validation";

Maintenant, vous pouvez utiliser votre service comme suit (index est implicite):

import {XyService} from "../../../services";

Et une fois que vous avez plusieurs fichiers, cela devient encore plus facile:

import {XyService, MyOtherService, MyOtherSerivce2} from "../../../services";

Avoir à gérer ces fichiers supplémentaires est un peu plus de travail initial (le travail peut être éliminé avec mainteneur de tonneau ), mais j'ai trouvé que cela en valait la peine avec moins de travail. Il est beaucoup plus facile d'effectuer des modifications majeures de la structure des répertoires et de réduire le nombre d'importations à effectuer.

Mise en garde

Ce faisant, il y a quelques choses que vous devez surveiller et que vous ne pouvez pas faire:

  1. Vous devez surveiller les réexportations circulaires. Donc, si les fichiers de deux sous-dossiers se référencent, vous devrez utiliser le chemin complet.
  2. Vous ne devriez pas revenir en arrière dans un dossier du même dossier d'origine (par exemple, être dans un fichier du dossier de validation et faire import {XyService} from "../validation";). J'ai trouvé cela et le premier point peut conduire à des erreurs de non-définition des importations.
  3. Enfin, vous ne pouvez pas avoir deux exportations dans un sous-dossier portant le même nom. Habituellement, ce n'est pas un problème cependant.
122
David Sherret

Mieux vaut utiliser la configuration ci-dessous dans tsconfig.json

{
  "compilerOptions": {
    "...": "reduced for brevity",

    "baseUrl": "src",
    "paths": {
      "@app/*": ["app/*"]
    }
  }
}

Manière traditionnelle avant Angular 6: 

`import {XyService} from '../../../services/validation/xy.service';`

devrait être refactored dans ces:

import {XyService} from '@app/services/validation/xy.service

Court et doux!

6
Shivang Gupta

Je viens de tomber sur cette question. Je sais que cela fait longtemps maintenant, mais la réponse est plus simple pour quiconque le découvre.

Je suis tombé sur parce que quelque chose que je faisais depuis longtemps cesse de fonctionner et je me demandais si quelque chose avait changé dans Angular 7. Non, c'était juste mon propre code.

Quoi qu'il en soit, je n'ai eu à modifier qu'une seule ligne dans tsconfig.json pour éviter les longs chemins d'importation. 

{
  "compilerOptions": {
  "...": "simplified for brevity",

   "baseUrl": "src"
  }
}

Cela a fonctionné pour moi depuis que Angular-CLI est arrivé.

0
Chris Curnow