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 - 根相对导入的主要内容,如果未能解决你的问题,请参考以下文章
Angular2如何独立于html基本url设置应用程序根路径