【问题标题】:Should I create a module per component in Angular 4+ app?我应该在 Angular 4+ 应用程序中为每个组件创建一个模块吗?
【发布时间】:2018-03-08 04:07:21
【问题描述】:

我们有一个中型 Angular 4 应用程序(+-150 个组件)。

其中许多组件需要注入服务类并需要在应用程序中声明其他组件。

我们一直在尝试并发现对开发人员更友好的一种方法是为每个组件创建一个模块。模块导入子组件模块并提供(或导入)组件所需的所有服务。它还导出组件本身,以便其他组件可以通过模块引用它。

它使组件的组合变得轻而易举,并且组件的测试夹具的设置非常简单(这是以前重复依赖项和子组件树依赖项的地方)。
这种方法似乎与基于组件的架构相匹配,并允许围绕组件依赖项进行某种形式的封装。
感觉好得令人难以置信;)

我的问题是,拥有这么多模块对性能(或其他)有何影响?

【问题讨论】:

  • 感谢您的意见。这种方法大大缩短了我们的测试运行时间。从 700 次测试的 2 分钟 30 秒到 5 秒。开发人员开销要少得多;-) 嗯...不知道为什么我的问题被否决了。也许这表明其他人认为这是一个坏主意。
  • 我实际上认为这是这样做的方法,一个模块包括父组件和子组件,记住当 Angular 是 beta 版时,我们不能这样做......我们有一个用于大型应用程序的模块,那是友好的反面,不是马克所说的
  • 如果你正在开发一个库,每个组件都有一个模块通常是要走的路。例如,检查 ng-bootstrap。如果您正在开发应用程序,最好按功能对组件进行分组。 不知道为什么我的问题被否决了。 - 不要注意,这是 SO 的病
  • @Bob,您库的使用者可能会选择仅使用您库中的一个组件,因此导入该组件模块而不是具有多个组件的整个 lib 模块会很方便。跨度>
  • @MarkWhitfeld,是的,它们都被编译和合并了。您可以watch my talk at ngconf 或阅读模块上的my article。如果有问题,请提出问题:)

标签: angular


【解决方案1】:

我认为每个组件一个模块是设计 Angular 应用程序的最佳方式。

如果依赖其他组件,可以只包含与每个组件相关的组件模块,是直接依赖,不需要关心间接依赖.

一开始可能看起来工作量更大,但它会为您带来回报,减少维护问题。

如果 ComponentA 依赖于 ComponentB 则依赖于 ComponentC 创建:

ModuleCComponentC相关

ModuleB 与导入 ModuleCComponentB 相关

ModuleA与导入ModuleBComponentA相关(不需要直接导入ModuleC

如果ComponentB 现在依赖于ComponentD(例如在模板中包含<my-component-d>)并停止依赖于ComponentC,您只需更改ModuleB 并且所有依赖于ComponentB 的组件都可以正常工作,如果您正在使用这种方法。

现在想想数百个组件。有多少组件将取决于ComponentB

我认为这个问题与在脚本标签中包含 js 文件的旧方式(或不太旧)类似:

<script src="build/a.js"></script>
<script src="build/b.js"></script>
<script src="build/c.js"></script>

如果您将b 更改为停止依赖c 并开始依赖d,则所有导入b 的页面现在都必须导入d,以此类推,导致维护噩梦。您也可能忘记删除(现在不需要的)c.js 并在某些页面中不必要地导入它,从而增加您的启动时间(或更糟,您从所有导入 b.js 的文件中删除它,但是某些页面导入了依赖于c.jse.js,并且您破坏了该页面的某些功能。

相反,我认为导入更好:

<script src="build/bundle.js"></script>

<script src="build/vendor.js"></script>
<script src="build/main.js"></script>

并且依赖关系由模块捆绑器处理,例如webpack

有一种方法是制作一个包含大量组件的模块,然后只导入它,但你最终会导入几个你不使用的组件,如果你使用延迟加载,您的模块可能会变得很大,除非您在 AppModule 中导入该模块,从而使您的启动时间增加

您仍然可以使用每个模块一个组件的方法与功能模块。只需将组件模块导入功能模块(而不是组件本身):

feature.module.ts:

imports: [
    ComponentAModule,
    ComponentBModule,
    ComponentCModule,
]

(您可能也想导出它们)。

我也认为这种方法是创建库时的最佳方式,否则你会强制库的使用者导入所有组件,即使他们只使用 1或库中的 2 个组件。

我遇到了ionic3 的这个问题:缩小的ionic-angular 库有437KB 其中292KB 是组件(希望它会随着ionic4 而改变)。我只使用了几个ionic 组件,没有必要全部导入,但我别无选择(除非我分叉回购或停止使用它)。

我有一个包含 176 个组件的应用程序,我认为这是最好的方法。之前,我在一个功能模块中包含了几个组件,这让我后来有些头疼。此外,将一个组件从一个功能模块更改为另一个更难(它的依赖关系如何?它们都混合在一起)。

我还没有找到令人满意的服务方法 (@Injectable())。

最终由您决定。这是我根据我的经验得出的看法。

【讨论】:

  • 感谢您的回答卢卡斯。尽管这个问题很大程度上取决于人们对应用程序结构的看法,考虑到他们的上下文,我确实相信这是一个非常好的方法。在我的应用程序中采用这种方法后,我体验了您提到的所有好处。为每个组件创建一个模块的少量工作无疑提高了应用程序的可维护性和可组合性。显然,模块构造通过编译消失了,因此它甚至不会增加开销。谢谢你的回答。
  • @MarkWhitfeld 是的!就我而言,最大的问题是最初的从几个组件的单体模块到每个组件一个模块,但现在我只需要在创建新组件时创建新模块,创建模块所需的时间肯定很多比创建组件本身(使用逻辑和模板)要少,所以我将模块创建视为组件创建的一部分,现在更改组件之间的依赖关系和删除未使用的依赖关系要容易得多。
  • 你会为每个@Pipe 使用一个模块吗?
  • @LucasBasquerotto,谢谢您的回答。我的 Angular 7.x 应用程序使用女士加载,并有一个 SharedModule 包含跨延迟加载模块使用的共享组件。我已经重构了应用程序,现在每个组件都有一个用于共享组件的模块。在重构之前和之后,我运行了npm run aot:块的总大小减少了 7.6%。所以谢谢你的建议:-)
  • @Yanal-YvesFargialla 酷!但主要原因甚至不是最终的包大小,而是在初始加载时加载的大小(这会影响应用程序在启动时的性能)。启动时加载的内容越少越好。理想的场景是只在启动时加载真正需要的内容(虽然其他模块可以异步加载,比如不影响初始加载,但让延迟加载的模块启动更快)。
猜你喜欢
  • 2020-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
相关资源
最近更新 更多