如何避免Angular 2中具有很长相对路径的导入?

Tho*_*ler 85 typescript ecmascript-6 angular2-services angular

如何引入'my-app-name/services'类似以下导入的行?

import {XyService} from '../../../services/validation/xy.service';
Run Code Online (Sandbox Code Playgroud)

Dav*_*ret 128

TypeScript 2.0+

在TypeScript 2.0中,您可以baseUrltsconfig.json以下位置添加属性:

{
    "compilerOptions": {
        "baseUrl": "."
        // etc...
    },
    // etc...
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以导入所有内容,就像您在基本目录中一样:

import {XyService} from "services/validation/xy.service";
Run Code Online (Sandbox Code Playgroud)

除此之外,您还可以添加一个paths属性,该属性允许您匹配模式然后将其映射出来.例如:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "services/*": [
                "services/validation/*"
            ]
        }
        // etc...
    },
    // etc...
}
Run Code Online (Sandbox Code Playgroud)

哪个允许你从任何地方导入它:

import {XyService} from "services/xy.service";
Run Code Online (Sandbox Code Playgroud)

从那里,您将需要配置您正在使用的任何模块加载器以支持这些导入名称.现在,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";
Run Code Online (Sandbox Code Playgroud)

然后创建一个名为的文件my-app-name/services/index.ts并拥有以下代码:

export * from "./validation";
Run Code Online (Sandbox Code Playgroud)

现在您可以像这样使用您的服务(index隐含):

import {XyService} from "../../../services";
Run Code Online (Sandbox Code Playgroud)

一旦你有多个文件,它就会变得更容易:

import {XyService, MyOtherService, MyOtherSerivce2} from "../../../services";
Run Code Online (Sandbox Code Playgroud)

必须维护这些额外的文件需要更多的工作(使用桶维护者可以消除工作),但我发现它最终会以较少的工作得到回报.执行主要目录结构更改会更容易,并且会减少您必须执行的导入数量.

警告

这样做有一些你必须注意的事情,不能做:

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

  • **angular-cli用户**:如果您使用的是angular-cli 2+,则会切换到webpack和blackboxed webpack.config.js(在node_modules内)._"从那里,你需要配置你正在使用的任何模块加载器来支持这些导入名称."_由于webpack.config.js是黑盒子,你不能做这件事.幸运的是,我发现这个问题已经报道[这里](https://github.com/angular/angular-cli/issues/1465)并由[this]解决(https://github.com/angular/angular- cli/pull/2470)PR.**TL; DR**黑盒子webpack配置足够智能,现在可以查看tsconfig.json. (10认同)
  • 一个小技巧 - 在阅读文档后发现`baseUrl`是相对于'tsconfig.json'的位置.所以在我们的情况下(角度应用程序),值必须是"baseUrl":"./ app",`,其中"app"是应用程序的根. (4认同)
  • 如何用npm下载Typescript 2.0+? (3认同)
  • @ThomasZuberbühler我认为打字稿1.8,这将是可用的([见这里](https://github.com/Microsoft/TypeScript/issues/5039)). (2认同)

Shi*_*pta 10

最好在tsconfig.json中使用以下配置

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

    "baseUrl": "src",
    "paths": {
      "@app/*": ["app/*"]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Angular 6之前的传统方式:

`import {XyService} from '../../../services/validation/xy.service';`
Run Code Online (Sandbox Code Playgroud)

应该重构为:

import {XyService} from '@app/services/validation/xy.service
Run Code Online (Sandbox Code Playgroud)

简短又甜蜜!


Chr*_*now 6

我刚刚遇到这个问题。我知道现在已经过去了,但对于任何遇到它的人来说,都有一个更简单的答案。

我之所以遇到这个问题,只是因为我长期以来一直在做的事情停止工作,并且我想知道 Angular 7 中是否发生了某些变化。不,这只是我自己的代码。

不管怎样,我只需要更改一行tsconfig.json即可避免长导入路径。

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

   "baseUrl": "src"
  }
}
Run Code Online (Sandbox Code Playgroud)

例子:

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

   "baseUrl": "src"
  }
}
Run Code Online (Sandbox Code Playgroud)

自从 Angular-CLI 出现以来,这对我来说非常有效。