如何避免在Angular 2中使用相对路径较长的导入?


Answers:


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属性,在使用多个项目时非常有用。

TypeScript 2.0之前的版本(仍适用于TS 2.0+)

我发现可以使用“ barrels”使其变得更容易。

  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";

不得不维护这些额外的文件需要做更多的事(可以使用barrel-maintainer消除工作),但是我发现最终可以减少工作量。进行主要的目录结构更改要容易得多,并且可以减少导入次数。

警告

在执行此操作时,您需要注意但不能做的几件事:

  1. 您必须注意循环再出口。因此,如果两个子文件夹中的文件相互引用,则需要使用完整路径。
  2. 您不应该从相同的原始文件夹返回一个文件夹(例如,位于验证文件夹中的文件中并执行import {XyService} from "../validation";)。我发现了这一点,第一点可能会导致无法定义导入错误。
  3. 最后,子文件夹中不能有两个具有相同名称的导出。通常,这不是问题。

2
@ThomasZuberbühler我认为它将在TypeScript 1.8中可用(请参阅此处)。
David Sherret

3
如何使用npm下载Typescript 2.0+?
maximedupre

4
一个小技巧-阅读文档后,发现baseUrl相对于'tsconfig.json'的位置。因此,在我们的示例(角度应用程序)中,值必须为"baseUrl": "./app",,其中“ app”是应用程序的根。
Pawel Gorczynski

10
只适用于angular-cli用户:如果您使用的是angular-cli 2+,他们将切换到webpack和黑盒化webpack.config.js(在node_modules内部)。 “从那里,您将需要配置用于支持这些导入名称的任何模块加载器。” 由于webpack.config.js已被黑盒包装,因此您不能这样做。幸运的是,我发现此问题已在此处报告并已由 PR 解决。TL; DR黑盒化webpack配置非常聪明,现在可以查看tsconfig.json。
凯文(Kevin)

1
对于angular-cli用户,您可以使用“ ng弹出”生成一个webpack.config。请注意,您需要从.angular-cli.json->项目中删除弹出的:true,以便能够为该项目提供服务。
Drusantia '17

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.