¿Cómo evitar importaciones con rutas relativas muy largas en Angular 2?

Respuestas:

138

TypeScript 2.0+

En TypeScript 2.0 puede agregar una baseUrlpropiedad en tsconfig.json:

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

Luego puede importar todo como si estuviera en el directorio base:

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

Además de esto, puede agregar una pathspropiedad, que le permite hacer coincidir un patrón y luego trazarlo. Por ejemplo:

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

Lo que le permitiría importarlo desde cualquier lugar así:

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

A partir de ahí, deberá configurar el cargador de módulos que esté utilizando para admitir también estos nombres de importación. En este momento, el compilador de TypeScript no parece asignarlos automáticamente.

Puede leer más sobre esto en el número de github . También hay una rootDirspropiedad que es útil cuando se utilizan varios proyectos.

Pre TypeScript 2.0 (todavía aplicable en TS 2.0+)

Descubrí que se puede hacer más fácil usando "barriles" .

  1. En cada carpeta, cree un index.tsarchivo.
  2. En estos archivos, vuelva a exportar cada archivo dentro de la carpeta.

Ejemplo

En su caso, primero cree un archivo llamado my-app-name/services/validation/index.ts. En este archivo, tenga el código:

export * from "./xy.service";

Luego cree un archivo llamado my-app-name/services/index.tsy tenga este código:

export * from "./validation";

Ahora puede usar su servicio así ( indexestá implícito):

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

Y una vez que tiene varios archivos, se vuelve aún más fácil:

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

Tener que mantener estos archivos adicionales es un poco más de trabajo por adelantado (el trabajo se puede eliminar usando el mantenedor de barril ), pero he descubierto que al final vale la pena con menos trabajo. Es mucho más fácil hacer cambios importantes en la estructura de directorios y reduce la cantidad de importaciones que tiene que hacer.

Precaución

Al hacer esto, hay algunas cosas que debe vigilar y que no puede hacer:

  1. Tienes que estar atento a las reexportaciones circulares. Por lo tanto, si los archivos de dos subcarpetas hacen referencia entre sí, deberá utilizar la ruta completa.
  2. No debe volver a una carpeta de la misma carpeta original (por ejemplo, estar en un archivo en la carpeta de validación y hacerlo import {XyService} from "../validation";). Encontré esto y el primer punto puede provocar errores de importación que no se definen.
  3. Finalmente, no puede tener dos exportaciones en una subcarpeta que tengan el mismo nombre. Sin embargo, generalmente eso no es un problema.
David Sherret
fuente
2
@ ThomasZuberbühler Creo que en TypeScript 1.8 estará disponible ( ver aquí ).
David Sherret
3
¿Cómo puedo descargar TypeScript 2.0+ con npm?
maximedupre
4
Un pequeño consejo: después de leer la documentación, resultó que baseUrles relativo a la ubicación de 'tsconfig.json'. Entonces, en nuestro caso (aplicación angular) el valor tenía que ser "baseUrl": "./app",, donde "aplicación" es la raíz de la aplicación.
Pawel Gorczynski
10
Solo para usuarios de angular-cli : si está usando angular-cli 2+, cambiaron a webpack y a webpack.config.js en caja negra (dentro de node_modules). "A partir de ahí, deberá configurar cualquier cargador de módulo que esté utilizando para admitir también estos nombres de importación". Dado que webpack.config.js está en caja negra, no puede hacer esta pieza. Afortunadamente, descubrí que el problema ya se informó aquí y este PR lo resolvió . TL; DR la configuración del paquete web en caja negra es lo suficientemente inteligente como para ver tsconfig.json ahora.
Kevin
1
para los usuarios de angular-cli, puede generar un webpack.config con "ng eject". Tenga en cuenta que deberá eliminar el expulsado: true de .angular-cli.json -> proyecto para poder servir el proyecto.
Drusantia
14

Es mejor usar la siguiente configuración en tsconfig.json

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

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

Forma tradicional antes de Angular 6:

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

debe refactorizarse en estos:

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

¡Corto y dulce!

Shivang Gupta
fuente
este cambio no funciona en producción @shivangGupta
anónimo
1

Acabo de encontrarme con esta pregunta. Sé que está muy atrás ahora, pero para cualquiera que lo encuentre, hay una respuesta más simple.

Me encontré solo porque algo que había estado haciendo durante mucho tiempo dejó de funcionar y me preguntaba si algo había cambiado en Angular 7. No, era solo mi propio código.

Independientemente, solo tuve que cambiar una línea tsconfig.jsonpara evitar rutas de importación largas.

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

   "baseUrl": "src"
  }
}

Ejemplo:

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

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

Esto me ha funcionado prácticamente desde que apareció Angular-CLI.

Chris Curnow
fuente
Gracias por el esfuerzo Chris, ¡pero deberías haber proporcionado ejemplos de uso en tu respuesta!
George43g