Как избежать импорта с очень длинными относительными путями в Angular 2?


Ответы:


139

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 и черный ящик 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 ->, чтобы иметь возможность обслуживать проект.
Drusantia

14

Лучше использовать конфигурацию ниже в tsconfig.json

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

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

Традиционный способ до Angular 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.