ChatGPT解决这个技术问题 Extra ChatGPT

我应该在 Angular 4+ 应用程序中为每个组件创建一个模块吗?

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

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

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

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

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

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

L
Lucas Basquerotto

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

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

起初它可能看起来更多的工作,但它会给你带来更少的维护问题。

如果 ComponentA 依赖于 ComponentB 而依赖于 ComponentC 创建一个:

ModuleCComponentC 相关

ModuleB 与导入 ModuleCComponentB 相关

与导入 ModuleBComponentA 相关的 ModuleA(不需要直接导入 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 中导入那个模块,使您的启动时间增加。

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

功能模块.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 酷!但主要原因甚至不是最终的包大小,而是初始加载时加载的大小(这会影响应用程序在启动时的性能)。启动时加载的内容越少越好。理想的情况是只在启动时加载真正需要的内容(尽管其他模块可以异步加载,例如不影响初始加载,但使延迟加载的模块启动更快)。