内容简介:在 Nrwl,我们帮助财富500强公司用正确的方式使用 Angular 平台开发。这些公司很少存在小型应用,大多是多个团队使用多个共享库构建的多个应用程序。经历过此种情况的开发者就知道,如果处理不当它很快就会演变成一个多对多的卷积噩梦。在本文中,我将会讨论:文章的末尾——在讨论了一些相关因素和关注点之后——我将列出一份大型组织中架构师的12条清单,以提高他们团队的工作效率。
在 Nrwl,我们帮助财富500强公司用正确的方式使用 Angular 平台开发。这些公司很少存在小型应用,大多是多个团队使用多个共享库构建的多个应用程序。经历过此种情况的开发者就知道,如果处理不当它很快就会演变成一个多对多的卷积噩梦。
在本文中,我将会讨论:
- 为什么开发大型 Web 应用在大公司很难
- 为什么 Angular 是大公司的绝佳选择
- 怎么做
文章的末尾——在讨论了一些相关因素和关注点之后——我将列出一份大型组织中架构师的12条清单,以提高他们团队的工作效率。
大型组织面临的挑战
从表面上看,大型和小型组织实际上都有同样的关注点:
- 他们关注一致性 。如果每个团队构建代码的方式不统一,则代码将难以复用和集成。
- 他们需要编写健壮,经过验证的代码 :包括错误处理,竟态条件等。
- 他们需要编写可维护的,自文档化的代码。
- 他们希望能够放心地更改代码 。如果开发人员可以快速验证更改是否安全,那么他们更有可能保证代码库拥有更少的bug。
大型组织的不同之处在于,他们拥有数百名 Angular 工程师,并且构建了数十个应用程序,拥有大量的代码,从而导致了新的挑战。
- 虽然十名开发人员可以通过午餐聊天达成最佳实践的共识,但当开发人数达到五百名时就不现实了。 你必须建立最佳实践,团队标准并使用 工具 来推广它们 。
- 随着代码量和复杂性的提升,代码所有权概念变得非常重要。例如,只有三个项目的情况下,大家往往都知道团队内谁是 review PR 的最佳人选,但三十个项目的时候就不是这样了。 你必须明确定义所有权模型并使之自动化 。
- 例如,在只有三个项目的情况下,开发人员很容易知道在代码变更后需要重新测试哪些内容,但有三十个项目时,这不再是一个简单的过程。管理变更的非正式规定将不再适用于大型团队,多团队和多项目协作的情形。 你必须依赖自动化 CI 流程 。
换句话说,小型组织通常可以通过非正式的临时流程来实现这些目标,而大型组织却不能。临时流程也会使得团队中新加入的开发人员更加困惑且容易出错。
Angular 是让大型组织受益的框架
作为 Angular(2.x及更高版本)的主要贡献者之一,不出意料地我肯定认为 Angular 是各种规模,无论大小的公司的绝佳选择。但是,我想强调一下为什么该框架特别适合大型组织的几个理由。
没有碎片
Angular 社区并不分散。几乎所有应用程序都是由 Angular CLI 构建的,使用 Angular router,许多应用程序使用 NgRx(或计划使用它)来管理状态和副作用。 这种统一性导致高度的一致性 。因此,当新的开发人员加入团队时,他可以在几天内就能变得高产,他也可以在组织内换岗的同时保持高效。
语义化版本控制
Angular 每六个月发布一个新版本。如果推出重大变更,你将有一年的时间来更新你的应用。虽然这会使得像我这样的框架贡献者的工作更加艰难(例如,我无法立马修复路由设计中的错误),但是能让像我一样的 Angular 用户更容易帮助公司业务获得成功。
Angular :heartpulse: TypeScript
TypeScript 是 JS 生态系统中最棒的发明之一,它为开发人员提供了开发时警告和错误提示,它还能够帮助我们阐明代码意图并消除歧义(阅读这里了解更多)。 Angular 并不是唯一适用于 TypeScript 的框架——大多数现代框架都可以。 但它是整个生态系统与 TypeScript 配合良好的唯一主流框架 :每个工具和每个库。因此,typings 定义永远不会过时,API 与类型一起使用时开发体验很棒,代码操作工具背后使用了 TypeScript 编译器 API。
使用 TypeScript 作为通用语言让 Angular 与其他框架有着很大的区别。
自动化
大型组织依赖于工具和自动化。这通常意味着源代码必须是可静态分析的。而 Angular 就是以此为基础构建的,它清晰地分离了应用程序的静态和动态部分,使你能够编写可靠的工具来操作 Angular 源代码。此外,开发人员可以利用工具来构建,测试,运行和打包 Angular 应用程序,而无需开发人员配置任何内容。
怎么做
对你所在的组织来说,开发大型应用影响最大的四个主要因素分别是:
- 代码管理,
- 依赖管理,
- 落地最佳实践,以及
- 自动化。
我们来详细阐述一下。
代码/依赖关系管理
正如我上面提到的,大型组织存在有很多代码,很多开发人员对代码,包,部署等进行过更改。因此,弄清楚如何托管它,如何有效地对其进行修改,如何在不同项目之间建立依赖关系,如何构建和发布它们,是你需要尽早给出方案的问题。一旦开始研究这些问题,你将发现并非所有项目/模块都类似。
在典型的项目配置中,有四类项目/模块:
- Apps ,这些是你交付的业务产品。
- 特定于 App 的 lib ,这些是可以独立开发和测试的 app 部分。
- 可复用的 lib ,这些是你在多个不同 App 中使用的组件,服务和工具。
- 第三方库和工具。
在这个模式下,开发人员应该能够:
- 创建 app 特定的 lib
- 提取可复用的 lib
- 验证更改可复用 lib 相关的代码不会破坏任何依赖它的 app 和 lib
- 同时重构多个 app 和 lib
- 确定 app 和 lib 的负责 Owner
开发人员完成所有这些工作的难易度,对团队的迭代速度和项目的代码质量有很大影响。
如果创建一个新的可复用库(需要新建一个 repo,配置 CI,发布到内部 npm 仓库)需要耗费一天的时间,那么很少有人会愿意这样做。因此,开发人员会不自觉地复制粘贴代码,或者把代码放到不恰当的地方。 如果能在几分钟内(而不是几天)构建和配置可复用库...那么才会促进开发人员建立和维护可重用的库。
如果多个 app 依赖于多个 lib,则在 lib 更改时,回归测试会变得非常困难。如果无法自动验证可复用库的更改会不会破坏任何 app,那么开发人员将害怕进行代码更改并编写防御性的脆弱代码。
如果开发人员无法横跨不同的 app 和 lib 进行重构,他们就不会改进 API。
当开发人员无法独立构建和测试 app 部分时,他们将会创建内部模块紧密耦合的单体应用。当他们能够(使用 app 特定的 lib)做到时,他们就会编写更多可维护的代码并改进他们的应用程序架构。
这主要是因为他们必须明确定义一个特性的依赖以及它的输出,这个过程必须仔细斟酌,其结果类似于六边形体系结构,减少了项目之间的耦合。
Nrwl Nx 是一个用于企业级 Angular 应用的开源工具包,基于 Angular CLI 构建,它解决了很多上面提到的问题。 通过使用 monorepo 的方式,把多个 app 和 lib 托管在同一个 repo (在这里阅读更多相关信息)。
借助 Nrwl / Nx 开发人员可以:
- 快速创建 app 特定的 lib
- 快速提取可复用的库
- 验证可复用 lib 的代码变更不会破坏任何依赖它的 app 和 lib(Nx 附带增量构建和测试仅受 PR 影响的 app 的命令)
- 同时重构多个 app 和 lib
Nx 强制你使用第三方库的单一版本(虽然必要时可以绕过它),这一点很重要。如果你的 app 和 lib 依赖于 TypeScript 的不同版本,则它们可能无法被复用。而且使用不同的库组合可能会导致难以调试的问题。即使你不使用 Nx,我依然建议创建一个名为 third-party 的软件包,列出主要的第三方依赖项,并使其他 app 和 lib 依赖于它。
Nx 并不处理代码的所有权问题,因为这取决于代码的托管方式。如果使用 GitHub,则可以利用 CODEOWNERS 文件 。
无论你是否选择使用 Nx,请确保明确定义上述五个操作的工作流程,记录在文档里,衡量下开发人员执行这些操作的速度。
落地最佳实践和自动化
Code review 和口耳相传是落地小团队最佳实践的好方法。但是,组织越大,此过程就越耗费资源,容易出错,并且很难统一。这时我们就需要使用工具来解决此问题。
创建小型可复用 lib
往往最简单的事情可能会产生最大的影响。
例如,创建可复用的小型 lib。即使只把 30 行代码提取到可复用的 lib 中,你也可以提高团队的工作效率并节省数周的工作量。
例如,Nrwl 团队观察到每一个单独的应用都存在很多竟态条件。其中一些是显而易见的,而另一些是非常微妙的,很难溯源。即使是经验最丰富的高级工程师也难免会忽视微妙的竟态条件。
在帮助许多客户解决这些类型的问题后,我们不得不问自己:“我们能否建立一个小工具来消除(或避免)产生竟态条件的代码?”
因此,我们实现了一个 50 行代码的 service,该 service 与 NgRx Effects 集成,消除了 Web 应用中出现的许多竟态条件。这个功能的代码量非常小,你可以阅读它的源码并能很快了解它的作用。我们把它变成了 Nx 的一部分。你应该鼓励你团队的开发人员也这样做,可以从导致最多问题的三个方面开始:测试,状态管理和路由。
创建 Schematics 实现代码生成
Angular CLI 使用 schematics 库进行代码生成。 Nrwl / Nx 基于 Angular CLI 构建,它通过定制一个自定义的 schematics 集合,为多 app/多 lib 项目定制 CLI 功能。企业团队应该更进一步,创建一个你所在组织中使用的 schematics 集合。例如,如果在集成测试中使用模拟数据,请创建 schematics 以生成相应填充素材。
通过衡量开发人员实现简单代码生成器所需的时间,只有在花费仅需几分钟的时候,人们才会这样做。
创建自定义 Lint 规则
TSLint 擅长两件事:确保开发人员不会犯下低级错误,并使代码风格更加统一。TSLint 可以在 CI上 运行,并且还可以与所有主要编辑器和 IDE 集成。
引入这个工具,做好相关配置,并通过文档记录执行 TSLint 检查的流程,以便开发人员可以快速执行。
使一切自动化(使用代码格式化工具)
令人惊讶的是,很少有组织会配置代码自动格式化等流程。很大程度上,是因为许多人认为这不是开发的重点。如果需要数周的时间才能配置正确,那么我同意。但是,实际上,它可能只需要30分钟,并且具有惊人的效果:它使代码风格更加统一,并且消除了一大堆问题。
团队使用格式化工具协作的最大好处是利于代码提交和代码审查。代码的变更作为整个仓库的增量,不应该引入混乱的格式来影响一些关键代码的修改。
Nrwl Nx 附带了一些命令来在本地和 CI 中设置代码自动格式化。
TLDR/架构清单
这里列出了一份大型组织里架构师的清单列表,可以帮助他们的团队提高工作效率。
- 定义 用于构建 Angular 应用(CLI,Nx,NgRx)的工具集 。开发人员喜欢搭建自定义构建工具,但使用标准工具往往是更好的选择,至少从长远来看是这样。创建一个使用这些工具构建的示例仓库。
- 定义 创建/提取新库的过程 。 衡量下需要多长时间。
- 定义 一个流程,用于验证代码更改为可复用 lib 不会破坏任何依赖它的 app 和 lib ,区分本地开发和 CI 环境。衡量下需要多长时间。
- 定义 重构多个 app 和 lib 的流程 。
- 定义 分配和检查模块所有权的流程 。没有良好的所有权模式,开发就会产生混乱。
- 定义 分支管理策略 :基于主干的开发或基于功能的开发,试着让所有 app 和 lib 都统一。
- 定义 显式地管理第三方依赖关系的策略 。
- 定义 状态管理和副作用管理最佳实践 ,使之尽可能自动化。
- 定义 测试最佳实践 ,使之尽可能自动化。
- 从一开始就创建一个 特定于组织的 tslint 包 。这是推广最佳实践的好方法。
- 从一开始就创建一个 特定于组织的 schematics 包 。这是推广最佳实践的好方法。
- 自动化所有可自动化的内容(例如, 配置代码自动格式化 )。
不出所料,Nrwl Nx 帮助我们实现了很多其中的功能。毕竟,这就是我们创造它的原因。但是这与大多数架构的决策一样,并不是说仅仅使用某个工具就好,而是要仔细地选择工具和流程。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法概论
Sanjoy Dasgupta、Christos Papadimitriou、Umesh Vazirani / 王沛、唐扬斌、刘齐军 / 清华大学出版社 / 2008-7 / 39.99元
《国外经典教材·算法概论》涵盖了绝大多数算法设计中的常用技术。在表达每一种技术时,阐述它的应用背景,强调每个算法运转背后的简洁数学思想,注意运用与其他技术类比的方法来说明它的特征,并提供了大量相应实际问题的例子。《国外经典教材·算法概论》同时也注重了对每一种算法的复杂性分析。全书共10章,从基本的数字算法人手,先后介绍了分治、图的遍历、贪心算法、动态规划、线性规划等技术,对NP完全问题进行厂基本而......一起来看看 《算法概论》 这本书的介绍吧!