Jak uniknąć importu z bardzo długimi ścieżkami względnymi w Angular 2?

96

Jak mogę wprowadzić coś takiego, 'my-app-name/services'aby uniknąć wierszy takich jak następujący import?

import {XyService} from '../../../services/validation/xy.service';
Thomas Zuberbuehler
źródło

Odpowiedzi:

139

TypeScript 2.0+

W TypeScript 2.0 możesz dodać baseUrlwłaściwość w tsconfig.json:

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

Następnie możesz zaimportować wszystko tak, jakbyś był w katalogu podstawowym:

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

Ponadto możesz dodać pathswłaściwość, która umożliwia dopasowanie wzorca, a następnie zmapowanie go. Na przykład:

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

Co pozwoliłoby ci zaimportować go z dowolnego miejsca, takiego jak:

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

Stamtąd będziesz musiał skonfigurować dowolny moduł ładujący, którego używasz do obsługi tych nazw importu. Obecnie wydaje się, że kompilator TypeScript nie mapuje ich automatycznie.

Możesz przeczytać więcej na ten temat w numerze github . Istnieje również rootDirswłaściwość przydatna podczas korzystania z wielu projektów.

Pre TypeScript 2.0 (nadal ma zastosowanie w TS 2.0+)

Odkryłem, że można to ułatwić używając "beczek" .

  1. W każdym folderze utwórz index.tsplik.
  2. W tych plikach ponownie wyeksportuj każdy plik w folderze.

Przykład

W twoim przypadku najpierw utwórz plik o nazwie my-app-name/services/validation/index.ts. W tym pliku umieść kod:

export * from "./xy.service";

Następnie utwórz plik o nazwie my-app-name/services/index.tsi miej ten kod:

export * from "./validation";

Teraz możesz korzystać z usługi w następujący sposób ( indexjest to domniemane):

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

A gdy masz tam wiele plików, staje się jeszcze łatwiejsze:

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

Konieczność utrzymywania tych dodatkowych plików wymaga trochę więcej pracy z góry (pracę można wyeliminować za pomocą narzędzia do konserwacji beczek ), ale okazało się, że ostatecznie opłaca się przy mniejszym nakładzie pracy. Znacznie łatwiej jest wprowadzać duże zmiany w strukturze katalogów i zmniejsza liczbę importów, które musisz wykonać.

Uwaga

Robiąc to, musisz uważać na kilka rzeczy, a których nie możesz zrobić:

  1. Musisz uważać na cykliczny reeksport. Jeśli więc pliki w dwóch podfolderach odwołują się do siebie, musisz użyć pełnej ścieżki.
  2. Nie powinieneś wracać do folderu z tego samego oryginalnego folderu (np. Będąc w pliku w folderze walidacji i robiąc import {XyService} from "../validation";). Znalazłem to i pierwszy punkt może prowadzić do błędów importu, który nie jest zdefiniowany.
  3. Wreszcie nie możesz mieć dwóch eksportów w podfolderze o tej samej nazwie. Zwykle jednak nie stanowi to problemu.
David Sherret
źródło
2
@ ThomasZuberbühler Myślę, że w TypeScript 1.8 będzie dostępny ( patrz tutaj ).
David Sherret,
3
Jak mogę pobrać Typescript 2.0+ za pomocą npm?
maximedupre
4
Mała wskazówka - po przeczytaniu dokumentacji okazało się, że baseUrljest on powiązany z lokalizacją 'tsconfig.json'. Tak więc w naszym przypadku (aplikacja kątowa) wartość musiała być "baseUrl": "./app",, gdzie „aplikacja” jest katalogiem głównym aplikacji.
Paweł Gorczyński
10
Tylko użytkownicy angular-cli : jeśli używasz angular-cli 2+, przeszli oni na webpack i blackboxed webpack.config.js (wewnątrz node_modules). „Stamtąd musisz skonfigurować dowolny program ładujący moduły, którego używasz, aby obsługiwał również te nazwy importu”. Ponieważ plik webpack.config.js jest na czarnej skrzynce, nie możesz tego zrobić. Na szczęście okazało się, że problem został już tutaj zgłoszony i rozwiązany przez ten PR. TL; DR konfiguracja pakietu webpack w czarnej skrzynce jest wystarczająco inteligentna, aby teraz spojrzeć na tsconfig.json.
Kevin
1
dla użytkowników angular-cli można wygenerować plik webpack.config z "ng eject". Zauważ, że musisz usunąć ejected: true z .angular-cli.json -> project, aby móc obsłużyć projekt.
Drusantia
14

Lepiej użyć poniższej konfiguracji w tsconfig.json

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

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

Tradycyjny sposób przed Angular 6:

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

należy refaktoryzować na te:

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

Krótkie i słodkie!

Shivang Gupta
źródło
ta zmiana nie działa w produkcji @shivangGupta
anonimowy
1

Właśnie natknąłem się na to pytanie. Wiem, że to już dawno, ale dla każdego, kto go spotka, istnieje prostsza odpowiedź.

Trafiłem tylko dlatego, że coś, co robiłem przez długi czas, przestało działać i zastanawiałem się, czy coś się zmieniło w Angular 7. Nie, to był tylko mój własny kod.

Niezależnie od tego musiałem zmienić tylko jedną linię, tsconfig.jsonaby uniknąć długich ścieżek importu.

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

   "baseUrl": "src"
  }
}

Przykład:

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

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

To działało dla mnie prawie od czasu pojawienia się Angular-CLI.

Chris Curnow
źródło
Dzięki za wysiłek Chris, ale w swojej odpowiedzi powinieneś był podać przykłady użycia!
George43g