Angular2 - root相对导入

时间:2016-01-05 15:04:37

标签: typescript angular

我对angular2 / typescript中的导入有问题。我想使用像“app / components / calendar”这样的根目录的导入,而只能使用类似的方式:

//app/views/order/order-view.ts
import {Calendar} from '../../components/calendar 

其中Calendar定义如下:

//app/components/calendar.ts
export class Calendar {
}

这显然会越严重,你去的等级越低,最深的是' ../../..'但它仍然非常糟糕和脆弱。有没有办法如何使用相对于项目根目录的路径?

我在Visual Studio中工作,相对导入似乎是VS能够识别这些imports.y的唯一东西。

6 个答案:

答案 0 :(得分:22)

答案

从TypeScript 2.0开始,您可以将tsconfig.json属性设置为baseUrl,如下所示:

{
  "compilerOptions": {
    "baseUrl": "app"
}

然后,您可以使用所需的方式导入组件,例如:

import { Calendar } from 'components/calendar';

附录

后备路径解析

一个重要的考虑因素是指定baseUrl选项会导致TypeScript编译器:

  1. 查找与baseUrl相关的路径
  2. 如果解决方案失败(找不到模块),请查找与moduleResolution选项
  3. 相关的路径

    SystemJS

    由于SystemJS在Angular开发阶段大量使用,因此请务必同时配置systemjs.config.js,以便正确解析路径。

    来源及进一步详情:https://github.com/Microsoft/TypeScript/issues/5039

答案 1 :(得分:14)

简短回答

将compilerOption "moduleResolution"设置为"classic"

答案很长

您使用的是tsconfig.json吗?我猜你是。我一直在寻找一种方法,将import someModule = require ("../../../../someModule"等语句发送到import someModule=require("src/path/to/someModule")。 我发现浪费了几个小时后tsc可能会使用不同的算法来解决模块问题。我使用atom并创建tsconfig.json,并将compilerOption属性moduleResolution设置为"node",并使用节点的shitty(借用我的法语)模块解析算法。我只是把#34;经典"并开始以明显的方式工作。

**更新**

不要使用此解决方案。拥抱node module resolution algorithm。 社区依赖于它,所以如果你试图不这样做,一切都会破裂。使用别名或其他一些提供的解决方案。

答案 2 :(得分:7)

一种方法是让文件重新导出并使用较短的路径捆绑文件。

您可以在应用程序的根目录中使用./ / p>创建components.ts文件夹

export {Calendar} from './components/calendar'
export {*} from './components/map'

组件

导入
import {Calendar, Map} from '../../components';

然而,这将更适合导出模块,以便其他人可以使用它们,而不是构建项目的方式。

另一种方法是放弃使用import语句,而是使用内部模块。

calendar.ts

module Components {
    export class Calendar {}
}

您可以在项目中的任何文件中使用它。

new Components.Calendar();

或者使用别名导入它。

import Calendar = Components.Calendar;
new Calendar();

答案 3 :(得分:4)

Tl;博士:您现在应该可以使用src作为根,它将“正常工作”。

使用Angular 2.0,当您运行ng new my-proj时,它会自动创建文件my-proj/src/tsconfig.app.json。此文件包含baseUrl行:

"baseUrl": "./",

因此,您不必更改有关配置的任何内容,并且可以将所有导入范围限定在src。假设您的项目结构类似于:

my-proj/
  README.md
  src/
    app/
      sidebar/
        sidebar.component.ts
      user.service.ts

您可以使用以下内容导入文件:

import { Sidebar } from 'app/sidebar/sidebar.component';
import { UserService } from 'app/user.service';

编辑添加:Sublime不读取src/tsconfig.json,但它只读取顶级tsconfig.json(请参阅this issue)。如果Sublime中的导入行出现Cannot find module 'app/...'错误,您可以添加:

"baseUrl": "./src",

到您的顶级tsconfig.json文件。

答案 4 :(得分:2)

基本上,在Angular 6中,您可以从顶部底部开始import

我的两个选择

它们可用angular CLI生成的默认配置

  1. 从顶部开始
    如果它离应用程序的根更近,我更喜欢这种方式

    import { DateService } from "src/app/shared-services/context/date.service";

  2. 从底部开始

    import { DateService } from "../../../../../../../shared-services/context/date.service";

上下文:

TypeScript配置: tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  }
}


Angular的堆栈

ng -v

Angular CLI: 6.0.8
Node: 8.9.0
OS: win32 x64
Angular: 6.0.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.8
@angular-devkit/build-angular     0.6.8
@angular-devkit/build-optimizer   0.6.8
@angular-devkit/core              0.6.8

@angular-devkit/schematics        0.6.8
@angular/cli                      6.0.8
@ngtools/webpack                  6.0.8
@schematics/angular               0.6.8
@schematics/update                0.6.8
rxjs                              6.2.1
typescript                        2.7.2
webpack                           4.8.3

答案 5 :(得分:0)

您不需要从Angular-CLI生成的新Angular项目的默认配置中进行任何更改。不确定以前的版本,但是从版本6开始,我知道这是对的。要进行相对于根的导入,请在导入开始时使用src/app/,例如:

import { VideoPlayerComponent } from 'src/app/pages/shared/video-player/video-player.component';

与@MarekDulowski的answer相比,这是一个更好的解决方案,因为可以通过查询src/app/轻松识别和搜索相对于根目录的导入。

我从这里的解决方案中学到了这一点:https://stackoverflow.com/a/51582699/1253298