Come evitare le importazioni con percorsi relativi molto lunghi in Angular 2?


Risposte:


138

TypeScript 2.0+

In TypeScript 2.0 puoi aggiungere una baseUrlproprietà in tsconfig.json:

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

Quindi puoi importare tutto come se fossi nella directory di base:

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

Inoltre, potresti aggiungere una pathsproprietà, che ti consente di abbinare un modello e quindi mapparlo. Per esempio:

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

Il che ti consentirebbe di importarlo da qualsiasi luogo in questo modo:

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

Da lì, dovrai configurare qualsiasi caricatore di moduli che stai utilizzando per supportare anche questi nomi di importazione. In questo momento il compilatore TypeScript non sembra mapparli automaticamente.

Puoi leggere di più su questo nel problema di github . C'è anche una rootDirsproprietà che è utile quando si utilizzano più progetti.

Pre TypeScript 2.0 (ancora applicabile in TS 2.0+)

Ho scoperto che può essere reso più facile utilizzando "barili" .

  1. In ogni cartella, crea un index.tsfile.
  2. In questi file, riesportare ogni file all'interno della cartella.

Esempio

Nel tuo caso, crea prima un file chiamato my-app-name/services/validation/index.ts. In questo file, inserisci il codice:

export * from "./xy.service";

Quindi creare un file chiamato my-app-name/services/index.tse avere questo codice:

export * from "./validation";

Ora puoi usare il tuo servizio in questo modo ( indexè implicito):

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

E una volta che hai più file lì dentro diventa ancora più facile:

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

Dover mantenere questi file extra è un po 'più di lavoro in anticipo (il lavoro può essere eliminato usando il manutentore del barile ), ma ho scoperto che alla fine ripaga con meno lavoro. È molto più facile apportare modifiche importanti alla struttura delle directory e riduce il numero di importazioni che devi fare.

Attenzione

Quando lo fai ci sono alcune cose che devi guardare e non puoi fare:

  1. Devi guardare per riesportazioni circolari. Quindi, se i file in due sottocartelle fanno riferimento l'uno all'altro, dovrai utilizzare il percorso completo.
  2. Non dovresti tornare indietro di una cartella dalla stessa cartella originale (es. Essere in un file nella cartella di convalida e fare import {XyService} from "../validation";). Ho trovato questo e il primo punto può portare a errori di importazione non definiti.
  3. Infine non puoi avere due esportazioni in una sottocartella con lo stesso nome. Di solito questo non è un problema però.

2
@ ThomasZuberbühler Penso che in TypeScript 1.8 sarà disponibile ( vedi qui ).
David Sherret

3
Come posso scaricare Typescript 2.0+ con npm?
maximedupre

4
Un piccolo suggerimento: dopo aver letto la documentazione si è scoperto che baseUrlè relativo alla posizione di "tsconfig.json". Quindi nel nostro caso (applicazione angolare) il valore doveva essere "baseUrl": "./app",, dove "app" è la radice dell'applicazione.
Pawel Gorczynski

10
Solo utenti angular-cli : se stai usando angular-cli 2+, sono passati a webpack e webpack.config.js in blackbox (all'interno di node_modules). "Da lì, dovrai configurare qualsiasi caricatore di moduli che stai utilizzando per supportare anche questi nomi di importazione." Poiché webpack.config.js è in blackbox, non puoi fare questo pezzo. Fortunatamente, ho scoperto che il problema era già stato segnalato qui e risolto da questo PR. TL; DR la configurazione del pacchetto web in blackbox è abbastanza intelligente da guardare ora tsconfig.json.
Kevin

1
per gli utenti angular-cli, è possibile generare un webpack.config con "ng eject". Nota che dovrai rimuovere ejected: true da .angular-cli.json -> project per poter servire il progetto.
Drusantia

14

Meglio usare la configurazione di seguito in tsconfig.json

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

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

Modo tradizionale prima di Angular 6:

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

dovrebbe essere riformattato in questi:

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

Breve e dolce!


questa modifica non funziona nella produzione @shivangGupta
anonimo

1

Mi sono appena imbattuto in questa domanda. So che è tornato indietro adesso, ma per chiunque lo incontri c'è una risposta più semplice.

Mi sono imbattuto solo perché qualcosa che stavo facendo da molto tempo ha smesso di funzionare e mi chiedevo se qualcosa fosse cambiato in Angular 7. No, era solo il mio codice.

Indipendentemente da ciò, ho dovuto cambiare solo una riga tsconfig.jsonper evitare lunghi percorsi di importazione.

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

   "baseUrl": "src"
  }
}

Esempio:

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

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

Questo ha funzionato per me praticamente da quando è arrivato Angular-CLI.


Grazie per lo sforzo Chris, ma avresti dovuto fornire esempi di utilizzo nella tua risposta!
George43g
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.