Wie vermeide ich Importe mit sehr langen relativen Pfaden in Angular 2?

95

Wie kann ich so etwas einführen 'my-app-name/services', um Zeilen wie den folgenden Import zu vermeiden?

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

Antworten:

138

TypeScript 2.0+

In TypeScript 2.0 können Sie eine baseUrlEigenschaft hinzufügen in tsconfig.json:

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

Dann können Sie alles so importieren, als wären Sie im Basisverzeichnis:

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

Darüber hinaus können Sie eine pathsEigenschaft hinzufügen , mit der Sie ein Muster abgleichen und dann zuordnen können. Beispielsweise:

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

So können Sie es von überall importieren:

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

Von dort aus müssen Sie den von Ihnen verwendeten Modullader konfigurieren, um auch diese Importnamen zu unterstützen. Derzeit scheint der TypeScript-Compiler diese nicht automatisch zuzuordnen.

Weitere Informationen hierzu finden Sie in der Github-Ausgabe . Es gibt auch eine rootDirsEigenschaft, die bei der Verwendung mehrerer Projekte hilfreich ist.

Pre TypeScript 2.0 (weiterhin anwendbar in TS 2.0+)

Ich habe festgestellt, dass es durch die Verwendung von "Fässern" einfacher gemacht werden kann .

  1. Erstellen Sie in jedem Ordner eine index.tsDatei.
  2. Exportieren Sie in diesen Dateien jede Datei innerhalb des Ordners erneut.

Beispiel

Erstellen Sie in Ihrem Fall zuerst eine Datei mit dem Namen my-app-name/services/validation/index.ts. Haben Sie in dieser Datei den Code:

export * from "./xy.service";

Erstellen Sie dann eine Datei mit dem Namen my-app-name/services/index.tsund haben Sie diesen Code:

export * from "./validation";

Jetzt können Sie Ihren Dienst wie indexfolgt nutzen ( impliziert):

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

Und sobald Sie mehrere Dateien darin haben, wird es noch einfacher:

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

Das Verwalten dieser zusätzlichen Dateien ist etwas mehr Arbeit im Voraus (die Arbeit kann mit Barrel-Maintainer beseitigt werden ), aber ich habe festgestellt, dass es sich am Ende mit weniger Arbeit auszahlt. Es ist viel einfacher, größere Änderungen an der Verzeichnisstruktur vorzunehmen, und es reduziert die Anzahl der Importe, die Sie durchführen müssen.

Vorsicht

Dabei gibt es einige Dinge, auf die Sie achten müssen und die Sie nicht tun können:

  1. Sie müssen auf zirkuläre Reexporte achten. Wenn sich Dateien in zwei Unterordnern gegenseitig referenzieren, müssen Sie den vollständigen Pfad verwenden.
  2. Sie sollten einen Ordner nicht aus demselben Originalordner zurücksetzen (z. B. in einer Datei im Validierungsordner und ausführen import {XyService} from "../validation";). Ich habe dies gefunden und der erste Punkt kann dazu führen, dass Importfehler nicht definiert werden.
  3. Schließlich können Sie nicht zwei Exporte in einem Unterordner mit demselben Namen haben. Normalerweise ist das aber kein Problem.
David Sherret
quelle
2
@ ThomasZuberbühler Ich denke in TypeScript 1.8 wird das verfügbar sein ( siehe hier ).
David Sherret
3
Wie kann ich Typescript 2.0+ mit npm herunterladen?
Maximedupre
4
Ein kleiner Tipp - nach dem Lesen der Dokumentation stellte sich heraus, dass das baseUrlrelativ zum Speicherort von 'tsconfig.json' ist. In unserem Fall (Winkelanwendung) musste der Wert also sein "baseUrl": "./app",, wobei "App" die Wurzel der Anwendung ist.
Pawel Gorczynski
10
Nur Angular-Cli -Benutzer : Wenn Sie Angular-Cli 2+ verwenden, haben sie zu Webpack und Blackpacked webpack.config.js (innerhalb von node_modules) gewechselt. "Von dort aus müssen Sie den von Ihnen verwendeten Modullader konfigurieren, um auch diese Importnamen zu unterstützen." Da webpack.config.js in einer Blackbox gespeichert ist, können Sie dieses Stück nicht ausführen. Zum Glück habe ich festgestellt, dass das Problem bereits hier gemeldet und von dieser PR behoben wurde . TL; DR Die Blackbox-Webpack-Konfiguration ist intelligent genug, um sich jetzt tsconfig.json anzusehen.
Kevin
1
Für Angular-Cli-Benutzer können Sie eine webpack.config mit "ng eject" generieren. Beachten Sie, dass Sie das ausgeworfene: true-Projekt aus .angular-cli.json -> entfernen müssen, um das Projekt bedienen zu können.
Drusantia
14

Verwenden Sie besser die folgende Konfiguration in tsconfig.json

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

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

Traditioneller Weg vor Winkel 6:

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

sollte in diese umgestaltet werden:

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

Kurz und bündig!

Shivang Gupta
quelle
Diese Änderung funktioniert nicht in der Produktion @shivangGupta
anonym
1

Ich bin gerade auf diese Frage gestoßen. Ich weiß, dass es schon lange her ist, aber für jeden, der darauf stößt, gibt es eine einfachere Antwort.

Ich bin nur darauf gestoßen, weil etwas, das ich schon lange getan hatte, nicht mehr funktionierte und ich mich fragte, ob sich in Angular 7 etwas geändert hatte. Nein, es war nur mein eigener Code.

Unabhängig davon musste ich nur eine Zeile ändern tsconfig.json, um lange Importpfade zu vermeiden.

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

   "baseUrl": "src"
  }
}

Beispiel:

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

// after:
import { XyService } from 'app/services/validation/xy.service';

Das hat bei mir seit Angular-CLI ziemlich gut funktioniert.

Chris Curnow
quelle
Vielen Dank für die Mühe, Chris, aber Sie hätten in Ihrer Antwort Verwendungsbeispiele angeben sollen!
George43g