发布于 2026-01-05 5 阅读
0

Angular 模块最佳实践 2021 DEV's Worldwide Show and Tell Challenge Presented by Mux: Pitch Your Projects!

Angular 模块最佳实践 2021

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

Angular 模块用于组织应用程序,并将组件、指令和管道整合到功能块中。

好的策略可以改善代码组织结构,优化打包大小,并使应用程序更易于扩展和重构。而糟糕的策略则可能导致依赖地狱和过大的打包体积。

在这篇博客中,我将介绍不同的策略,并就如何为您的申请选择合适的策略提供一些建议。

目录

  • TLDR;
  • 示例应用
  • 方面
  • 策略
  • 概括

TLDR;

我从包大小、可扩展性、简洁性和样板代码等多个方面来比较不同的模块策略。

结果是,没有一种策略可以适用于所有类型的应用程序,但这篇文章应该可以帮助您在选择策略的过程中找到答案。

示例应用

我将向您展示我如何组织一个应用程序。它既不是简单的计数器,也不是大型企业应用。因此,它可能不适用于您的应用规模,但我认为这是一个不错的应用程序开发框架。

我们以音乐播放器为例。对大多数人来说,这应该是一个非常熟悉的应用程序。它底部有一个全局播放器,还有几个用于查找和浏览歌曲的视图。

文件夹结构

我们暂时抛开 Angular 模块,来看看如何构建我们的应用程序。

文件夹结构和代码组织方式是主观的,取决于你正在开发的应用程序。这只是为你提供一些应用程序结构方面的思路。

我使用三个主要文件夹:

  • 共享
  • 浏览

Views包含我们可以路由到的 3 个视图:

  • 房屋视图
  • 搜索视图
  • 专辑视图

核心组件包含了应用启动时需要使用的所有组件,包括界面外壳和底部菜单。此外,迷你播放器和全屏播放器也包含在核心组件中。

共享组件包含视图之间共享的所有组件。在我们的示例中,我们有两个共享组件:

  • 横向专辑
  • 主标题

“视图特定组件”是我一开始没提到的一个文件夹(类型)。有些组件会在不同的视图中复用,有些则只在特定视图中使用。将代码尽可能放在使用位置附近是一种良好的编程实践。因此,我们将只在特定视图中使用的组件放在该视图文件夹中。在本例中,搜索栏就只在搜索视图中使用。

使用 Angular 模块

现在可以使用 Angular 模块将这些组件组合成模块。将应用程序拆分成 Angular 模块的方法有很多种,没有绝对的对错之分。

方面

在决定采用哪种方法时,我们应该考虑以下几个方面。

模块的分割方式会影响包的大小。这可能包括整体包的大小,也可能包括各个懒加载包的大小。这会影响应用在浏览器中的加载时间。

可扩展性是指代码易于浏览和修改的程度。根据应用程序的结构,代码重组的难度也会有所不同。

简单性是指团队成员能够多容易地理解何时以及在哪里创建 Angular 模块。

样板代码:我们的 Angular 模块需要多少样板代码?模块越多,样板代码就越多。这通常可以通过使用 CLI 或 IDE 生成样板代码来解决。

可测试性:测试单个组件有多容易?如果该组件是大型模块的一部分,我们可能需要模拟许多服务。

策略

今天我想重点探讨以下三种策略:

  • 所有功能都在一个模块中
  • 每个功能/视图一个模块(延迟加载)
  • 每个组件一个模块(SCAM)

所有策略都有其优缺点。雷达图以可视化的方式对比了不同的方法。

将所有组件放在一个模块中非常简单。每当我们创建一个组件时,只需将其添加到 app.module 声明中即可。

这种方法非常简单,但也有一些缺点:

  • 所有组件均采用预加载方式,这会导致初始加载时间延长。
  • app.module 文件变得臃肿,重构意味着要不断修改这个文件。
  • 解决依赖关系简直是噩梦。例如,删除一个组件后,很难确定哪些依赖项需要移除。也许某个组件只在被删除的组件中使用,而我们却漏掉了它。

这种方法可能适用于非常小的应用,但我不建议将其用于大型项目。

每个组件一个模块(SCAM)与之前的方法截然相反。在这种策略中,我们为每个组件创建一个单独的模块。SCAM 是“Single Component Angular Module”(单组件 Angular 模块)的缩写。Lars Gyrup Brink Nielsen 在这篇博文中创造了这个术语。

我喜欢这种方法的一点是,它更容易理解组件的依赖项。每个组件模块只导入它直接使用的模块。这意味着如果我们移除一个组件,它的所有依赖项也会自动移除。真不错。

这种方法的另一个好处是,由于依赖关系树清晰,Angular 可以为延迟加载路由构建最佳的捆绑包。

最后,也是非常重要的一点,规则非常简单:每个组件都有自己的模块。就是这样,无需讨论如何对模块进行划分。

我唯一看到的缺点是,由于模块定义更多,而且必须显式导入所有依赖项,因此会增加一些样板代码。但未来随着 `@Component` 装饰器新 API 的推出,这种情况可能会有所改变,新 API 允许使用独立组件(无需 NgModules)。更多信息,可以关注GitHub 上的相关讨论

每个功能/视图使用一个模块(延迟加载)可能是最常见的模式。

当我们延迟加载所有视图时,可以获得最佳的打包大小。由于共享模块被多个延迟加载的模块使用,因此它会被加载到一个单独的公共模块中。关于这方面的更多细节,我写了一篇关于 Angular 如何打包模块的博客文章:《Angular 模块打包》

这种模式介于其他两种方法之间。它既能减少代码包的大小和样板代码,又能保持清晰的结构。

如果你的应用规模较大,你还可以将模块进一步拆分成更小的功能模块,或者将视图打包成更大的功能包。这既可以帮助你组织代码,也可能导致你对何时创建这些子模块感到困惑。Angular 的官方文档是了解这种模式的好帮手。

如何决定使用哪种图案?

最简单的决定就是排除将所有功能都放在一个模块中的可能性。如果应用程序有路由并且组件超过 10 个,就不要采用这种策略。

要在视图/功能模块和单组件模块之间做出选择,您需要问自己以下问题:

为了清晰的依赖关系树和简单的规则,你愿意添加多少样板代码?

只要功能模块的导入和声明是可管理的,采用经典的功能/视图模块方法仍然是我的首选方法。

如果你要构建一个库,SCAM 策略非常理想,因为它允许库的使用者只导入他们使用的组件。此外,由于其规则简单,如果你难以定义一个好的策略,SCAM 策略也很适用。

SCAM 和传统的特性/视图模块方法都会生成相同的包结构,因此从性能角度来看,两者都非常出色。但是,前提是我们没有意外地在应用或核心模块中导入特性模块,而 SCAM 不会出现这种情况。

概括

在这篇博客文章中,您学习了不同的模块策略以及诸如包大小、可扩展性、简洁性和样板代码等各个方面,这有助于您决定采用哪种策略。

我在这里展示的三种策略是我主要看到和了解的。如果你使用其他策略,请告诉我,也许我很快就会更新博客文章,添加新的策略🙃

如果你喜欢这篇文章🙌,请分享出去,并在Twitter上关注我,获取更多关于网络技术的文章。

你发现错别字了吗🤓?请帮助我们改进这篇博文,并在此处提交问题或发表你的反馈。

文章来源:https://dev.to/this-is-angular/angular-modules-best-practices-2021-3lo5