如何跨角度模块正确导入/导出类?

2024-03-05

这个问题来自于企业应用的背景。

从我读过的所有书籍和我见过的关于角度应用程序的在线示例中,每次我们创建一个类(组件、服务、实体等)时,我们都会在类型定义上导出它们,然后在需要的地方直接导入它们引用(类似于在 C# 上使用命名空间),无论两个类属于相同或不同的 Angular 模块。

Ex:

// In 'Commons/logger.service.ts'
export class LoggerService { ... }

// In 'Core/common.service.ts'
export class CommonService { ... }

// In 'Products/' module
import { LoggerService } from '../Commons/logger.service'
import { CommonService } from '../Core/common.service'

export class ProductComponent { ... }

我开始从事一个(大型)企业应用程序项目,并注意到一种我以前从未见过的方法,他们创建文件来收集每种类型的类(服务、实体、方法参数、组件),导出其中的每一个,导出其中的每一个这些文件位于其相应的角度模块文件上,然后不是直接从类型文件导入类型,而是从给定模块执行导入。

前面的示例将转换为如下所示:

// In 'Commons/logger.service.ts'
export class LoggerService { ... }

// In 'Commons/services.ts'
export * from './logger.service.ts'
export * from './other.service.ts'
export * from './another.service.ts'

// In 'Commons/commons.module.ts'
export * from 'services.ts'
export * from 'entities.ts'
/* ... */


// In 'Products/' module
import { LoggerService, OtherService } from '../Commons/commons.module'

export class ProductComponent { ... }

鉴于这种方法比以前的方法要详细得多,并且在某些情况下会引起尴尬的结果(如果在同一模块中导入类,则会出现循环引用警告)

我的问题是:

  1. 从良好设计或最佳实践的角度来看,推荐哪种方法?
  2. 是否比前者更推荐这种方法?为什么?适用于哪些情况?
  3. 为什么这种方法没有在主要文档来源(Angular 在线文档、Angular 书籍等)中引入?
  4. 这种方法的优点和缺点是什么。

这是一个称为桶文件的概念。这些文件使导入类更加方便。这不仅仅是 Angular 的一个概念。使用它们似乎是 TypeScript 的最佳实践。

当您有一个较小的项目时,您可能看不到创建这些文件的太多好处,但是当您与多个团队成员一起处理较大的项目时,它们会非常有用。以下是我所知道的一些优点/缺点。

优点:模块内部结构所需的知识较少

当组件需要引用某些内容时,它不必知道类等所在的确切文件。当您不将这些内容存储在模块内时,模块外部的所有其他文件都将需要确切地知道哪个文件(包括子路径)包含该项目。如果您将物品放入单个模块桶中,您只需知道它来自哪个模块即可。这还为您带来了重构模块的好处,不需要您确保在文件移动时更新路径(您的工具可能会或可能不会帮助解决此问题)。

// without barrel files
import { Class1 } from 'app/shared/module1/subpath1/subpath2/class1.service';

// using barrel files
import { Class1 } from 'app/shared/module1';

优点:显式导出外部模块

另一个好处是,一个模块可能包含一堆类、接口等,这些类、接口等实际上只在该模块内使用。通过为模块创建桶文件,您可以让其他开发人员知道在模块外部使用的内容。此外,您让他们确切地知道要使用哪些项目,因此他们不需要到处寻找他们需要的界面(同样,您的工具可能会或可能不会对此提供帮助)。

// export these items from module as others need to have references to these
export { ExampleModule } from './example.module';
export { ExampleService } from './example.service';
export { ExampleInterface } from './example.model';

// these also exist in module but others don't need to know about them
// export { ExampleComponent } from './example.component';
// export { Example2Service } from './example2.service';
// export { ExampleInterface2 } from './example.model';

优点:更清洁的进口

我要提到的最后一个好处是它有助于清理您的进口。它不仅可以更清楚地显示哪些项目来自哪些模块,还有助于使from导入的部分要短得多,因为您不需要遍历子目录等。请注意,最佳实践似乎是将桶文件index.ts位于文件夹中,因为当给定要从中导入的文件夹时,TypeScript 编译器将默认查找该文件。

// without barrel files (hopefully they would be not randomly ordered to make it even harder...)
import { Class1 } from 'app/shared/module1/subpath1/subpath2/class1.service';
import { Class2 } from 'app/shared/module1/subpath1/class2.component';
import { Interface1 } from 'app/shared/module1/module1.model';
import { Class3} from 'app/shared/module2/subpath3/class3.service';
import { Interface2 } from 'app/shared/module2/module2.model';

// using barrel files
import { Class1, Class2, Interface1 } from 'app/shared/module1';
import { Class3, Interface2 } from 'app/shared/module2';

缺点:附加文件

在尝试识别缺点时,我唯一能想到的是您正在为每个模块创建另一个文件(或者可能是子文件夹,具体取决于您想要如何执行此操作)。据我所知,它没有运行时或编译时效果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何跨角度模块正确导入/导出类? 的相关文章

随机推荐

  • Apache 文件缓存

    apache 如何处理某些文件的缓存 是否可以通过给定主机或虚拟主机的标准配置文件明确指出某些文件应该比其他文件更积极地缓存 具体来说 我在各种 XML 文件中保存了大量网站内容 并且我希望能够说该文件将被大量使用 因此会尽可能多地缓存它
  • 如何将 https://example.com/ 重定向到 https://www.example.com/

    我的代码中有这个代码 htaccess文件如下图所示 RewriteEngine On RewriteCond HTTPS off RewriteRule https HTTP HOST REQUEST URI 添加此内容是为了将 http
  • 多进程 vs 多线程 Python 耗时

    我有 2 个简单的函数 在一定范围内循环 可以单独运行而无需任何依赖 我正在尝试使用 Python 多处理模块和多线程模块来运行这两个函数 当我比较输出时 我发现多进程应用程序比多线程模块多花费 1 秒 我读到 由于全局解释器锁 多线程效率
  • 在 Java 中使用 Mockito 模拟枚举

    如何使用 Mockito 模拟枚举以进行测试 给出枚举的示例 public enum TestEnum YES NO 这是使用枚举的方法 public static boolean WorkTheEnum TestEnum theEnum
  • fopen 与 unicode 文件名

    我必须使用一个接受文件名作为字符串的库 const char 内部文件打开方式为fopen 有没有办法让这个库接受 unicode 文件名 我可以用吗宽字符到多字节 http msdn microsoft com en us library
  • 如何处理打字稿中异步函数的返回值? [复制]

    这个问题在这里已经有答案了 caseService 函数处理 HTTP 请求和响应并返回单个对象 我想归还对象 但由于它是一个异步功能 因此它返回空对象 this caseBook 我希望它仅在对象具有价值后才返回该对象 public in
  • Keycloak 8:已添加用户名“admin”的用户

    我无法使用 Ansible 和 Docker Compose 启动 Keycloak 容器 我收到错误 用户名 admin 的用户已添加到 opt jboss keycloak standalone configuration keyclo
  • 如何展平散列,使每个键成为唯一值?

    我想采用带有嵌套哈希和数组的哈希 并将其展平为具有唯一值的单个哈希 我一直试图从不同的角度来解决这个问题 但后来我把它变得比需要的更加复杂 让自己迷失在正在发生的事情中 源哈希示例 Name gt Kim Kones License Num
  • ArangoDB 和用户定义的函数或存储过程

    ArangoDB 文档 Foxx 部分 说 由于 Foxx 直接在 ArangoDB 内部运行 因此您可以将处理请求所需的所有数据库查询和逻辑捆绑在一个位置 除了使用 Foxx 框架 之外 还有其他 更原生 的方法来实现与 ArangoDB
  • 在 ASP.Net 中编写自定义 NTLM 质询/响应

    我知道您可以启用 NTLM验证在 ASP Net 应用程序中使用
  • 通过 React setState 使用子键的计算值

    我希望能够使用计算值sub keys在 React 中更新状态时 我了解如何在简单的设置中使用计算值 如下所示 this setState name value 但我在让键值计算适用于这样的情况时遇到困难 constructor props
  • 在 iPhone 中将 NSTimeInterval 转换为 NSString?

    如何将 NSTimeInterval 转换为字符串 我有 NSTimeInterval today NSDate date timeIntervalSince1970 我必须将 今天 作为 NSString 的输入 NSTimeInterv
  • 使用可配置键进行 Swift 4 JSON 解码

    我是 Swift 新手 我需要用一些东西来解析 JSON可配置按键 与我在这里看到的许多示例相反 密钥是已知的before解码操作开始 它们只依赖于传递给端点的一些参数 Example https some provider com end
  • 每个点都有时间序列的点之间的相关性下降

    我正在研究如何快速实现计算点 X Y Z 中 之间的相关性 并在给定搜索方向的情况下测量相关性何时低于某个阈值 我之前提出过一个相关问题计算点之间的相关性 其中每个点都有一个时间序列 https stackoverflow com ques
  • 在C程序中打印日语字符

    我想使用 C 程序打印日语字符 我找到了一些日语字符的 Unicode 范围 将它们转换为十进制并使用 for 循环来打印它们 setlocale LC ALL ja JP UTF8 for int i 12784 i lt 12799 i
  • 为什么@PrimaryKey val id: Int? = null 在创建 Room 实体时有效吗?

    我正在关注有关如何使用 Jetpack Compose 创建笔记应用程序的教程 这是tutorial https youtu be 8YPXv7xKh2w t 1227 教程中有一点是他创建了这个实体 Entity data class N
  • PHP 和 JavaScript cookie

    我可以用 PHP 访问用 jQuery 的 cookie 插件编写的 cookie 吗 我知道你不能将 Javascript 设置为等于 PHP 反之亦然 但本质上是 cookie var COOKIE var 再说一次 我知道你不能将它们
  • Java 8 Stream API min() 和 max() 与收集器 minBy() 和 maxBy() [重复]

    这个问题在这里已经有答案了 在 java 8 中 Stream API 帮助我们以非常干净且更少的代码完成我们的工作 我非常喜欢这些流 API 但是 很少有操作有助于解决同一类型的问题 并且不确定何时使用哪些操作 尽管在两者之间进行选择并不
  • 如何使用 Swift 在关闭 ViewController 期间将值从 ViewController B 传递到 ViewController A? [复制]

    这个问题在这里已经有答案了 我的场景 我试图传递值ViewController B to ViewController A在关闭视图控制器期间 这里我使用了下面的代码 但我无法获取其中的值ViewController A 视图控制器B pr
  • 如何跨角度模块正确导入/导出类?

    这个问题来自于企业应用的背景 从我读过的所有书籍和我见过的关于角度应用程序的在线示例中 每次我们创建一个类 组件 服务 实体等 时 我们都会在类型定义上导出它们 然后在需要的地方直接导入它们引用 类似于在 C 上使用命名空间 无论两个类属于