Angular2 - 根相对导入

Posted

技术标签:

【中文标题】Angular2 - 根相对导入【英文标题】:Angular2 - root relative imports 【发布时间】:2016-04-09 11:06:20 【问题描述】:

我在 angular2/typescript 中的导入有问题。我想使用像“app/components/calendar”这样的根目录的导入,而不是我能够使用的唯一方法是:

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

日历的定义如下:

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

这显然会变得更糟,层次越低,最深的是'../../..',但它仍然非常糟糕和脆弱。有什么方法可以使用相对于项目根目录的路径?

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

【问题讨论】:

"baseUrl" 也许应该设置 "./src"paths relate to it 让它工作,它起源于 "./" ,但我不工作,我不知道为什么!然后将"paths": "@app/*": ["app/*"] 添加到tsconfig.json 并使用import PageNotFoundComponent from '@app/error-page/page-not-found.component'; 【参考方案1】:

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

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

这是比@MarekDulowski 的answer 更好的解决方案,因为可以通过查询"src/ 轻松识别和轻松找到/搜索根相对导入。

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

【讨论】:

【参考方案2】:

更新

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

简答 有办法,但你不应该这样做。 将 compilerOption "moduleResolution" 设置为 "classic"

长答案

你在使用tsconfig.json吗?我假设你是。我一直在寻找一种将import someModule = require ("../../../../someModule" 等声明变为import someModule=require("src/path/to/someModule") 的方法。 在浪费了几个小时后,我发现 tsc 可能会使用不同的算法来解决模块问题。我正在使用 atom ,它创建了 tsconfig.json 并将 compilerOption 属性 moduleResolution 设置为 "node" ,它使用了节点的糟糕(请原谅我的法语)模块解析算法。我只是输入“经典”并开始以明显的方式工作。

【讨论】:

"classic" 选项完全破坏了 angular2,你知道如何解决这个问题吗? 将源文件放在名为“node_modules”的文件夹中。在这个答案中有解释:***.com/a/24461606/2142728 将所有代码放在一个名为“node_modules”的文件夹中...这是另一个选项 这是我听说过@caeus 的最糟糕的选择 到目前为止支持@nottinhill 的 19 个人中是否有更好的解决方案?【参考方案3】:

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

我的两个选择

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

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

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

    从底部

    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

【讨论】:

【参考方案4】:

Tl;dr:您现在应该可以使用 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 文件。

【讨论】:

【参考方案5】:

回答

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


  "compilerOptions": 
    "baseUrl": "app"

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

import  Calendar  from 'components/calendar';

附录

后备路径解析

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

    查找关于 baseUrl 的路径 在解析失败(未找到模块)时,查找与 moduleResolution 选项相关的路径

系统JS

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


来源和更多详情:https://github.com/Microsoft/TypeScript/issues/5039

【讨论】:

@MerekDulwski ,我在一个问题中引用了您的解决方案,而 TSLint:***.com/questions/51292139/… 在遇到问题后,我实际上发现这不是理想的解决方案。我在这里发布了我的新首选解决方案:***.com/a/51599367/1253298 请试一试。 其实这是同一个解决方案。只是将baseUrl 选项设置为根项目目录 使它与我的建议不同,我同意,这不是最好的。我会更新我的答案,很高兴你找到了完美的解决方案。【参考方案6】:

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

您可以在应用程序的根目录中有一个 components.ts 文件夹。

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

并从组件

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

然而,与构建项目的方式相比,这种方式更适合导出模块以便其他人使用。

替代方法是放弃使用 import 语句并使用内部模块。

日历.ts

module Components 
    export class Calendar 

您将能够像这样在项目中的任何文件中使用它。

new Components.Calendar();

或者使用别名导入。

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

【讨论】:

以上是关于Angular2 - 根相对导入的主要内容,如果未能解决你的问题,请参考以下文章

为啥没有用于@angular/core 模块导入的相对路径

自己创建一个angular2工程(起步阶段)

Angular2如何独立于html基本url设置应用程序根路径

在 Angular2+Webpack 中使用 templateUrl 的相对路径

Angular2 相对路径在警卫中导航

从“@angular”而不是“angular2”导入 *