Як уникнути імпорту з дуже довгими відносними шляхами в Angular 2?


Відповіді:


138

TypeScript 2.0+

У TypeScript 2.0 ви можете додати baseUrlвластивість у tsconfig.json:

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

Тоді ви можете імпортувати все так, ніби знаходитесь у базовій директорії:

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

Крім цього, ви можете додати pathsвластивість, яка дозволяє вам зіставити шаблон, а потім нанести його на карту. Наприклад:

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

Що дозволить вам імпортувати його з будь-якого місця приблизно так:

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

Звідти вам потрібно буде налаштувати будь-який завантажувач модулів, який ви використовуєте для підтримки цих імен імпорту. Зараз, здається, компілятор TypeScript, здається, не автоматично відображає їх.

Ви можете прочитати більше про це у випуску github . Існує також rootDirsвластивість, яка корисна при використанні декількох проектів.

Pre TypeScript 2.0 (все ще застосовується в TS 2.0+)

Я виявив, що це можна зробити простіше, використовуючи "бочки" .

  1. У кожній папці створіть index.tsфайл.
  2. У цих файлах реекспортуйте кожен файл у папці.

Приклад

У вашому випадку спочатку створіть файл із назвою my-app-name/services/validation/index.ts. У цьому файлі мати код:

export * from "./xy.service";

Потім створіть файл із назвою my-app-name/services/index.tsта отримайте такий код:

export * from "./validation";

Тепер ви можете використовувати свою послугу так ( indexмається на увазі):

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

І як тільки у вас є кілька файлів, це стає ще простіше:

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

Потрібно підтримувати ці додаткові файли трохи більше роботи заздалегідь (роботу можна усунути за допомогою служби підтримки барелів ), але я виявив, що це врешті-решт окупається меншою роботою. Набагато простіше зробити основні зміни структури каталогів, і це скорочує кількість імпорту, який вам потрібно зробити.

Обережно

Роблячи це, є кілька речей, за якими потрібно стежити, але чого не можна робити:

  1. Ви повинні стежити за круговим реекспортом. Отже, якщо файли у двох вкладених папках посилаються один на одного, то вам потрібно буде використовувати повний шлях.
  2. Не слід повертати папку з тієї самої оригінальної папки (наприклад, перебуваючи у файлі в папці перевірки та виконуючи дії import {XyService} from "../validation";). Я виявив це, і перший пункт може призвести до того, що помилки імпорту не визначаються.
  3. Нарешті, ви не можете мати два експорти в підкаталозі з однаковим ім’ям. Зазвичай це не проблема.

2
@ ThomasZuberbühler Я думаю, що в TypeScript 1.8 це буде доступно ( див. Тут ).
Девід Шеррет,

3
Як я можу завантажити Typescript 2.0+ із npm?
maximedupre

4
Невеликий підказка - після прочитання документації виявилося, що baseUrlце відносно розташування 'tsconfig.json'. Отже, у нашому випадку (кутовий додаток) значення мало бути "baseUrl": "./app",, де "додаток" є коренем програми.
Павел Горчинський,

10
Лише для користувачів angular -cli : якщо ви використовуєте angular-cli 2+, вони перейшли на webpack та blackboxed webpack.config.js (всередині node_modules). "Звідти вам потрібно буде налаштувати будь-який завантажувач модулів, який ви використовуєте для підтримки цих імен імпорту." Оскільки webpack.config.js є в чорному ящику, ви не можете зробити цю частину. На щастя, я виявив, що про цю проблему вже повідомляли тут і вирішили цей PR. TL; DR конфігурація веб-пакета в чорному ящику достатньо розумна, щоб зараз подивитися tsconfig.json.
Кевін

1
для користувачів angular-cli ви можете створити webpack.config за допомогою "ng eject". Зверніть увагу, що вам потрібно видалити ejected: true з проекту .angular-cli.json ->, щоб мати можливість обслуговувати проект.
Друзантія

14

Краще використовувати нижче конфігурацію в tsconfig.json

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

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

Традиційний спосіб перед кутовим 6:

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

повинні бути перероблені на такі:

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

Короткий і солодкий!


ця зміна не працює у виробництві @shivangGupta
анонім

1

Я щойно натрапив на це запитання. Я знаю, що це вже давно, але для тих, хто стикається з ним, існує простіша відповідь.

Я зіткнувся лише з тим, що щось, чим я займався довгий час, перестало працювати, і мені було цікаво, чи щось не змінилося в Angular 7. Ні, це був лише мій власний код.

Незважаючи на це, мені довелося змінити лише один рядок, tsconfig.jsonщоб уникнути довгих шляхів імпорту.

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

   "baseUrl": "src"
  }
}

Приклад:

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

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

Це працює в мене майже з тих пір, як з'явився Angular-CLI.


Дякуємо за зусилля, Кріс, але у своїй відповіді ви мали б навести приклади використання!
George43g
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.