vlambda博客
学习文章列表

我是如何为 Angular Components 做出贡献的

作者 | Milko Venkov
译者 | 王强
策划 | 李俊辰

在这篇文章中,我想分享我对 @angular/components 的贡献,以及与谷歌团队合作维护它的经验教训。作为 Infragistics 的工程师,我手头的一项工作是 IgniteUI forAngular 组件库,负责开发和维护 IgxOverlayService。它允许在应用中的内容上层渲染一个 Angular 组件或一个 ElementRef,比如说对话框、下拉菜单、工具提示等。

几个月前,我研究了 Angular Components CDK(组件开发工具包),这组工具在实现通用交互模式的同时对其表示也不是 opinionated 的。它代表了在 Angular Material 库中核心功能的一个抽象,而没有任何专属 Material Design 的样式。可以把 CDK 视为经过良好测试的功能的一个空白状态,在此状态下你可以开发自己的定制组件。它提供的抽象之一是 overlay(叠加)服务。这项服务的功能与我在产品中负责的功能非常相似。Angular Components Overlay 服务还允许渲染 Angular 组件或模板以覆盖应用中的其他内容。这项服务看起来很合适。我决定不使用自己的服务,而使用 CDK 提供的这些服务。我开始调查 CDK overlay 是否符合我们的要求。

前期工作

我与 Infragistics 的管理层开了一个会,讨论了从 IgxOverlayService 切换到 Angular Components SDK Overlay 的可能性。我们的共识是,如果切换到 Angular 叠加服务,我们需要维护的代码会更少,并且我们将能为 Angular Components 开源项目做出贡献。最后,我们决定尝试切换到 SDK Overlay。为了实现这一转换,Infragistics 的开发人员得到许可,可以每天花几个小时为 Angular Components 做出贡献。

第一步,我分叉了存储库,构建了程序包,运行了 dev-app,并开始研究贡献流程和 Angular Components 团队遵循的标准。当我熟悉了代码后,便开始查看 GitHub 上的 Material Components 公共存储库中的问题。如果你想做出贡献,那么从文档入手是很好的选项。下面是你可行的一种入门策略:

  • 查看问题。

  • 选一个。

  • 尝试解决它。

你遇到的问题越多,你对代码以及组件的开发和工作方式就越熟悉。在贡献之前,请务必先阅读“对 Angular Material 做出贡献”指南。它将帮助你避免在开始使用开源项目时遇到的常见陷阱。

https://github.com/angular/components/blob/master/CONTRIBUTING.md

我是如何为 Angular Components 做出贡献的

新功能 

看过几个问题并开始熟悉这个库后,我看了一下 Overlay 服务,发现那里缺少我需要的某些特定功能。例如,它缺乏渲染纯 HTML 元素的能力,以及允许服务将其最终元素层次结构附加到 DOM 中特定位置的能力。于是我决定向 Angular Components 团队推荐新的功能,并尝试自己实现这些功能。

我和我的团队负责人与产品负责人一起,与 Angular Components 团队建立了联系。在几封电子邮件的交流之后,我们与对方开会讨论了叠加服务中所需的新功能。他们对我们为产品做出贡献的意愿感到高兴。他们还解释了向项目添加新功能的流程。最重要的一点是:不要破坏现有功能。正如他们所说,这个库已经用在了在成千上万的应用里,所以新的更改合并后应该不影响任何应用的工作。

设计文档

添加新功能的第一步是创建设计文档。你可以在 GitHub 的 Wiki 页面上找到 Angular Components 团队的所有设计文档的集合:

https://github.com/angular/components/wiki/Design-doc-directory

在编写设计文档之前,最好检查一下现有文档并使用推荐的模板来起步。在检查了 Overlay 设计文档以及更多现有文档之后,我为 Angular Components Overlay 中自己需要的每一项功能都编写了文档。这个过程很艰苦,对我来说很困难,但到最后是很有意义的。向框架添加新功能可能看起来很容易,但当你开始编写设计文档时,你会发现这是有多难的事情。你必须从各个角度审视新功能的工作机制,以及它与现有功能集成的方式。将所有这些内容写到文档中后,我就可以描绘出自己对所需功能的蓝图。例如,以下是我必须回答的一些问题:

  • 是否有另一个可以对比的实现?

  • 该功能如何实现?

  • API 会是什么?

等我完成了设计文档,它们就必须经过 Angular 团队的审查。Angular 团队的反应速度非常快。设计文档发过去后,第二天就得到了审核(你的时间表可能会有所不同)。我收到的所有评论都是简洁、积极和建设性的。在解决所有评论之后,我获得了实现功能的绿灯。

我关注的第一个功能是叠加层渲染 DOM 元素或 ElementRef 的能力。幸运的是,当我完成设计文档并被 Angular Components 团队接受后,他们告诉我该功能已经实现,并已包含在一个 PR 中。我查看了这个 PR,并请求了一些更改,因为我需要的某些更改已包含在该 PR 中。

    实现    

我实际开发的是自己需要的第二个功能,是在外部单击时关闭叠加层。想象一个模态对话框,你可以在对话框外部单击,然后它就会关闭。你可以在此处找到解释实现细节和先前工作的设计文档:

https://docs.google.com/document/d/18FIqx4EtAf16iz6lQ7Ndg0PX07C1zh6xF25QR3sPEkE/preview

设计文档获得批准后,我就开始写代码了。这个过程与修复错误没有太大的不同。我实现了该功能并添加了必要的测试。我在所有受支持的环境中进行了测试,然后推送了我的更改并创建 PR。接下来,Angular Components 团队的成员检查了我的 PR,并要求了一些更改。完成所有请求的更改后,该功能被添加到框架中。我的合并 PR 在这里:

https://github.com/angular/components/pull/16611

新功能帮助 Angular Components 团队解决了项目中记录的一些问题。例如,MatMenu 就使用了 SDK 的叠加层。当用户打开一个菜单时,显示的菜单会带 backdrop,使菜单变为模态的(issue 6927)。结果,当菜单打开时,用户将无法与应用程序项目交互。使用新的 detachOnOutsideClick 功能可以解决此问题。借助这一新功能还可以解决其他一些问题,例如 9320、15899 和 16036。

这个故事分享了我作为 Angular Component 贡献者的经验。一开始我是没什么头绪的。我不确定从哪里开始,不知道该如何协作。但如果你一步一步地往前走:找到所需的组件,进行调试以找出执行流程,并按照贡献流程行事,那么一切自然就会解决了。最后,我对自己的工作感到非常满意。我学到了很多东西:Angular 开发人员使用 RxJS 的方式、如何组织框架中的测试,等等。当然,为成千上万的工程师使用的项目做贡献的感觉也很棒。我还发现了负责项目的人们乐于接受新想法,并且非常友好。如果你有空闲时间,请大胆向前,检查 Angular Components 中的问题并挑一个解决吧!

延伸阅读

https://blog.angular.io/how-i-contributed-to-angular-components-b3a8830ca268