Angular2 - root相对导入

Jar*_*rek 36 typescript angular

我对angular2/typescript中的导入有问题.我想使用像'app/components/calendar'这样的root的导入,而只是我能够使用的方式是这样的:

//app/views/order/order-view.ts
import {Calendar} from '../../components/calendar 
Run Code Online (Sandbox Code Playgroud)

其中Calendar定义如下:

//app/components/calendar.ts
export class Calendar {
}
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ski 25

回答

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

{
  "compilerOptions": {
    "baseUrl": "app"
}
Run Code Online (Sandbox Code Playgroud)

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

import { Calendar } from 'components/calendar';
Run Code Online (Sandbox Code Playgroud)

附录

后备路径分辨率

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

  1. 查找关于baseUrl的路径
  2. 在失败的分辨率(找不到模块)上,查找与moduleResolution选项有关的路径

SystemJS

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


来源和进一步的细节:https://github.com/Microsoft/TypeScript/issues/5039


cae*_*eus 17

简短的回答

将compilerOption设置"moduleResolution""classic".

答案很长

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

**更新**

只是不要使用这个解决方案.拥抱节点模块解析算法.社区依赖于它,所以如果你试图不这样做,一切都会破裂.使用别名或其他一些提供的解决方案.

  • 这是我听过@caeus最可能的最糟糕的选择 (35认同)
  • 到目前为止,对@nottinhill赞助的19个人中有没有一个有更好的解决方案? (4认同)
  • "经典"选项完全打破了angular2,你知道怎么解决这个问题? (2认同)

Mar*_*n07 10

基本上,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";

语境:

打字稿配置: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"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)


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
Run Code Online (Sandbox Code Playgroud)


tos*_*skv 7

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

您可以在应用程序的根目录中包含components.ts文件夹.

export {Calendar} from './components/calendar'
export {*} from './components/map'
Run Code Online (Sandbox Code Playgroud)

并从组件导入它

import {Calendar, Map} from '../../components';
Run Code Online (Sandbox Code Playgroud)

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

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

calendar.ts

module Components {
    export class Calendar {}
}
Run Code Online (Sandbox Code Playgroud)

您可以在项目的任何文件中使用它,就像这样.

new Components.Calendar();
Run Code Online (Sandbox Code Playgroud)

或者使用别名导入它.

import Calendar = Components.Calendar;
new Calendar();
Run Code Online (Sandbox Code Playgroud)


kri*_*ina 5

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

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

"baseUrl": "./",
Run Code Online (Sandbox Code Playgroud)

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

my-proj/
  README.md
  src/
    app/
      sidebar/
        sidebar.component.ts
      user.service.ts
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令导入文件:

import { Sidebar } from 'app/sidebar/sidebar.component';
import { UserService } from 'app/user.service';
Run Code Online (Sandbox Code Playgroud)

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

"baseUrl": "./src",
Run Code Online (Sandbox Code Playgroud)

到您的顶级 tsconfig.json 文件。