浅谈大型项目中前端管理架构

今天来跟大家聊聊大型组织中(前端工程师的人数开始超过15人)前端管理架构,主要涉及的是团队协作。

本文不讨论在这样的大公司中常见的管理问题或业务领域问题,而是关注前端的协作架构。

如今,前端架构涉及的领域太多,因此,建议将其分为以下几部分:

 大型项目中前端组织架构

一、Visual Code

从最简单的主题开始,这是前端开发最常用的代码编辑器。

最可能是因为我们希望在同一家公司开发多个前端应用程序,所以我们希望它们具有:

  • 品牌认知度
  • 相同的UI/UX

为此,需要一个设计系统。设计团队必须提出设计规范,并在所有将来的产品设计中遵循这些设计准则。即使这已经是一个非常复杂的任务,并且需要设计团队、工程师和产品之间进行大量讨论和协调。

从前端的角度来看,需要提供一种工具来在工程师之间实施和共享此设计规范。为此,一个好的解决方案是创建npm软件包,该软件包将由Storybook或其他类似工具直观地呈现。我认为,拥有专用的Web资源(带有URL)以及有关如何使用此软件包的文档非常重要。该Web资源将由前端工程师和设计师使用,并且可以作为他们之间对话的重要参考。

小结:在这一点上,有一个设计规范及其在包中的封装和它的交互式文档。所有的前端应用程序中共享并采用这个package

二、代码结构

接下来谈谈日常编码,我们确实实现了新功能、修复了bug,如果需要的话重构代码。我们需要关注我们的代码库,试图让它变得友好和容易理解。但是,当我们的公司开始有不是1个、也不是2个,而是几十个大小项目时,会发生什么呢?

通常,人们围绕一些项目分组,并开始只与这组项目一起工作。由于人的本性和有限的时间,我们通常不能在一段时间内兼顾多于2-5个项目。所以很自然地,我们开始受到这些群体的影响。顺便说一句,感谢美国国家航空航天局(NASA)为我们提供了这么棒的照片。

但是,我们开始遇到越来越多的情况,当人们进行跨团队协作时,需要检查彼此的代码和解决方案,甚至在其他应用程序中也要修复一些错误,或者在某个外部应用程序(对于他们的小组来说是外部的)中添加他们需要的东西。影响力)。坏消息是,这一过程正在几乎不受控制的大公司中发生。好消息-我们可以帮助改善它。

怎么样?正确。通过为公司中的所有项目提供相同的代码结构,编码和结构准则。

让我们更深入地了解代码结构的含义:

  • 项目中的文件夹结构

    工程师第一次进入新项目时-与项目中的文件夹结构相同,他们知道所有内容都对导航和搜索有很大帮助。

  • 配置或支持性文件的

    文件,如package.json、.gitignore、.editorconfig、webpack.config等他们应该总是在同一个地方,在每一个项目。如果需要,将它们连接到测试配置文件或CI文件。

  • 文件类型的固定位置

    如果相同文件类型的位置始终遵循相同的结构,则效果也很好。例如,如果组件文件夹中始终有一个style.css文件:

    /Component
    --/Component.tsx
    --/style.css
    --/index.ts
    
  • 组件内部结构:文件内部的结构应相同:导入、导出的顺序、公共功能的位置、类型等。在每种类型的文件中,都应该知道期望的内容。

  • 命名规范:这包括文件夹、文件、变量、函数、类、类型等的名称

  • 编码约定:总的来说,编码约定是一个非常宽泛的部分,但是在这里我只想包含不适合其余部分的内容

在实践中,相同的代码结构和项目工具集非常紧密地结合在一起,有利于开发效率。我所说的工具集是指CLI工具(项目启动、检测、测试等)、IDE扩展等等。我们将在下一节中讨论工具集主题。

小结:在应用了本节并采用它之后,我们应该使组织中的所有项目都具有相同的文件夹结构、命名规范、文件结构等。理想情况下,每个开发人员都可以在项目之间无缝切换,不需要花额外的时间来学习和理解代码。

三、技术栈

与上一节类似,我们确实希望在组织的各个项目中拥有统一的技术栈。

在Frontend项目中,技术堆栈的组件可以是:构建该项目所基于的框架、主要语言、样式处理器、数据层(例如Apollo)、状态管理、测试、代码整理、构建系统等。

当然,所有规则中都有例外。在本主题中,我也想说一句,有时某些技术非常适合某些特定项目,即使这些技术不属于全球公司范围的技术堆栈。但是,每当这种想法脱离公司技术堆栈时,都应该三思而后行,因为支持此类事务的成本非常高,需要收益必须非常可观来支撑。

让我们在这里提及一些通用技术堆栈,该堆栈现在可以适合大多数项目(当然,它仅涵盖实际技术堆栈的一部分,但对于某人来说可能是一个很好的起点):

在我们为公司定义技术栈并达成共识之后,还有其他非常重要的成功支柱。

首先,我们需要写下来的技术堆栈的文件。这些文档应该在工程师之间方便且容易地共享,因此他们始终可以相互链接并维护。

其次,我们应该再次使用已定义的技术堆栈来写下并共享文档,以及如何启动和引导新项目的方式。

四、工具

这个话题很重要。现在,我们几乎在所有地方都使用了一些其他工具:整理、构建应用程序、CI、组件生成器等等。因此,这就是为什么能确定我们是否可以为项目选择正确的工具的原因至关重要。好的工具还是不好的工具(或者根本没有工具),就像自动化测试与手动测试之间的比较一样。

我们之前在前几节中谈到了技术堆栈和代码结构,并提到我们需要编写大量文档来使项目成员关注它们。但是正确的工具集可以有机会按照公司的准则进行自动化。

例如,如果具有指定的编码风格,则可以为项目提供linting工具集,该工具集默认情况下遵循这些规则。如果具有定义的技术堆栈,那么良好的CLI工具将提供机会,使用技术堆栈中的特定技术来引导新项目。

让我们尝试讨论工具可以覆盖前端体系结构的哪些部分:

  • 代码风格和结构:如我们之前所讨论的,可以通过工具轻松实现自动化

  • 项目自举:无需提出新的项目结构,手动安装所有需要的软件包等。

  • 组件生成:大多数情况下,应用程序中的某些组件甚至都不包含单个文件,因此文件创建、链接或者导入它们会花费一些时间,因此需要自动化。

  • 启动和构建:当然,最显而易见的要自动化的事情是如何构建或启动应用程序。

  • 测试:为测试构建应用程序并实际运行所有类型的测试(单元、集成等)的过程。

  • 依赖关系管理:现在大约80%的代码之间是有依赖关系。因此,需要让他们保持最新版本,并且要在大型公司中进行管理并非易事。

  • 跨项目的依赖关系:很可能我们的项目不是孤立地工作,可能依赖于其他项目,,因此我们可能需要一些工具来简化链接它们的过程,并结合多个项目(例如Bit等),等等。

  • CI:CI是我们日常工具集的重要组成部分,自动化和统一对您的组织可能是一项非常有益的工作。

如果不想开发自己的新工具集,我可以推荐NX工具集,它是最有趣的候选对象之一。同样,Babel的创建者似乎也执行了类似的解决方案,可能需要check out — Rome。这些工具并不能涵盖所有内容,而是我们所讨论内容的很大一部分,因此可以作为一个很好的起点。

小结:试想一下,在我们完成所有部分的采用之后,我们的体系结构将变得多么伟大。

每个项目都是相同的,并由统一工具集维护和管理。每个项目都可以以相同的方式启动和构建。新的组件在相同的位置使用相同的命名准则生成。

五、部署

通常,在前端体系结构的这一部分中,工程师最不用担心。也许是因为它在大多数时候都与编码本身无关,而且可能并不那么令人兴奋,但同样重要。

在生产中,我们通常需要注意以下事项:

  • Google Analytics(分析):各种不同的跟踪事件,例如Google Analytics(分析),Segment,HotJar等。

  • 状态监视:这包括诸如运行状况检查之类的内容,甚至可以在生产中运行测试,错误报告(例如Sentry)等。

*** 性能**:这与上一项相似,但更注重性能。这包括测量响应时间,第一个有意义的油漆等。(可能是工具#1- Lighthouse)

  • A/B测试:各种A/B测试解决方案或功能标记。

  • 缓存:诸如Varnish和Cloudflare之类的工具。

所有这些都可以在公司的前端应用程序中统一,这将简化工程师的工作。例如,通过添加具有预定义的初始配置的软件包,并将这些软件包添加到自举项目中。

生产的另一部分是代码准备,例如:

  • 缩小:只是代码缩小

  • 源映射:某些其他工具,例如Sentry,可能也需要源映射。

  • 资产准备:为具有不同分辨率的屏幕,裁切图像等做准备。

这些都是将要添加到我们用于管理前端应用程序的工具集中的不错的选择,我们在“工具”部分中已经讨论过。

六、开发

CLI工具

当我们接触前端CLI工具时,已经部分地在“工具”部分讨论了开发经验。统一工具是工程师日常工作的重要组成部分,但不是全部。

API

在本地使用舒适的API是我们改善开发人员体验和开发速度的第二件事。通常,为前端工程师在本地提供API并不是一件容易的事:这可能包括他们不熟悉的安装工具或框架。即使通过泊坞设置进行安装,这也可能会占用开发人员计算机的大量计算资源(如果不是,则可以将其视为安装)。在这种情况下,什么是解决方案-外部服务的API。对于所有工程师来说,这可以是一台服务器,也可以是某种机制来轻松引导您自己的专用服务器进行开发。

CI

CI是第三大部分。我可能认为,您的公司已经选择了一些CI工具作为前端并使用了该工具 (例如Circle CI,Concourse CI或任何其他工具)。如果不是,则应统一。

我认为,特定项目的CI配置应该是该项目团队的一部分。这给CI带来了稳定的机会,因为有些人对CI感兴趣,每天都要使用它,并且具有修复,配置和改进它的能力和技能。

但是,并非所有工作都应由团队完成。对于前端应用程序,存在相当特定的一堆作业,这可能是需要的。特别是,如果我们能够设法统一文件夹/代码结构,技术堆栈等。那么在您的公司工作一段时间后,也许可以在您的CI工具阶段检测到这些模式,将这些阶段实现为某种“构建基块”,并为您的工程师提供了一个机会,就是从这些统一的“构建基块”构建其CI管道。

演示环境

最后是最后-验证实现的功能。在工程师完成所有工作并实施之后,几乎总是需要某种方式来检查其外观和工作方式,并将其与其他工程师,设计师或其他利益相关者共享。对于此类需求,它可以通过提供的URL在特定PR的应用程序的临时部署版本中发挥出色的作用。

该解决方案大大加快了不同团队与人员之间的沟通,我认为这是必须具备的。但是,此临时部署的版本应尽可能接近生产环境,因为它也是检查某些表面错误或错误的好工具。

如果前端应用程序构建和部署流程管道是统一的,则可以轻松地将其添加到项目中并自动进行。同样,诸如Kubernetes和Helm之类的此类工具或类似工具也可以在实现中提供很大帮助。

小结:借助具有集成块的单个CI工具,使用统一的CLI前端工具和演示环境,即可轻松高效地进行开发流程。所有这些应使我们的开发过程尽可能顺利。

7、模块化

这个话题非常大,可能需要一篇单独的文章来讨论,但我会试着简要地介绍一下。

在大型组织中,庞大的代码库并不罕见。与所有已知的问题一起出现,如缓慢的CI管道、协作工作问题、缓慢的测试等。因此,前端架构的一个重要部分是决定我们希望看到独立前端应用/模块的粒度。

我们现在有三种主要的模式:

  • Monolith:一个大的存储库包含一个项目和所有的代码,所有的团队同时在这个存储库中工作。

  • Monorepo:很多项目,但仍然有一个很大的存储库(在wiki中是monorepo)。所有的团队仍然使用相同的存储库,但是使用的是不同的项目。我们已经有机会修复一些问题了,我们采用的是单一的方法,只针对特定的项目运行管道,项目有更小的测试套件等等。如果你选择了这种方法,像Lerna这样的工具可以让你的生活更简单。

  • Repo per project:每个项目都有自己的存储库和所有支持的东西,比如CI管道、部署等。

在所有这些模型中,项目可能意味着独立的前端应用程序、页面、独立的前端模块等等。这取决于您希望如何划分前端应用程序的粒度。在大多数情况下,这种划分应该与所需的组织结构和人员管理同步。

决定如何分割应用程序后的第二大主题是如何将这些部分连接在一起(如果你决定分割应用程序)。

这里我们有以下方法:

  • Build-time composition:项目可以只是npm软件包,可以在构建期间安装和组成。
  • Server-side composition:通常包括服务器端渲染和服务器上发生的合成。像Hypernova这样的工具可以帮助更好地组织它。
  • Client-side composition:浏览器内部项目的组成。非常重要的是要提到Module Federation,这是Webpack 5中引入的一种新方法。
  • Route composition:超级简单——每个项目都有自己的URL,在Nginx层级上我们决定把用户重定向到哪里。

就像我之前说的,用这么小的格式来涵盖这个主题是非常困难的,但我希望你至少能找到一些自己感兴趣的想法,并自己深入研究这个主题。

小结:我们找到了一种方法,通过组织存储库,将我们的项目分成更小的部分(最有可能),通过使团队更独立于彼此,使我们的团队快乐和富有成效。

八、测试

关于前端应用程序的测试,有很多可用的资源,所以我尽量不深入细节,而是更多地关注大型组织的问题以及我们如何解决它们。

第一步——每个工程师对测试技术的理解是不同的,以及在什么情况下应用哪种技术,如何编写“好的”测试,等等。所以非常有必要记录下公司所使用的测试水平的所有细微差别和指导方针,以及每个标准的指导方针。

你的测试策略中可能需要的测试级别:

  • 单元测试
  • 整体测试
  • 端到端测试
  • 其他的

此外,第二步,我们需要在公司的不同前端应用程序中统一它们,因此人们在迁移到其他项目时不会对如何以及如何进行测试有任何疑问。

如果设法统一了测试级别和方法,就可以自动帮助解决第二个问题——测试基础设施设置。每个项目都需要在本地和CI上设置和配置一些测试基础设施。例如,我们决定使用Cypress,它需要在docker镜像中运行。这需要一些时间在本地和CI上进行设置。如果我们把这个数字乘以我们所拥有的项目数量,那将是非常巨大的时间。因此,解决方案——再次统一并为项目提供一些工具。听起来很简单,但却需要大量的时间去实现。