原文:https://alexkondov.com/full-stack-tao-setting-up-the-project/

原标题:Setting Up the Project

作者:Alexander

你已经对该领域有了初步的了解,并确定了一个技术堆栈,现在开始编写你一直在头脑中构思的这个复杂功能。你已经看到 tRPC 集成和客户端状态在你眼前交织。

但在我们深入之前,还有一个前提条件:我们需要建立项目并确保可以顺利投入生产。

足够的配件工具

为了高效处理代码库,我们需要能运行、测试并良好地部署它的工具。根据我们选择的语言和框架,可能无法立即拥有这些工具。

我们至少需要一个 linter、一个格式化工具、一个测试工具和一个构建工具。

像 Go 这样的语言可以通过 CLI 获得所有这些功能,不需要任何外部包或配置。但以 JavaScript 为例,这是一个不小的工作量,尤其是在存储库中几乎没有代码的时候,这项工作更显得尤为重要。

如果我们在事后才考虑这个步骤,那么从一开始我们就会面对技术债务。

Linting 对于避免错误至关重要。格式化工具保证代码的一致性和可读性。测试(无论是单元测试、集成测试还是两者)确保稳定性。构建工具允许实际部署项目。

简单的本地开发

我们要尽可能简化生产步骤。但部署从你代码提交到分支的那一刻就开始了。

在你的机器上启动运行一个项目越困难,自动化构建和部署的过程就越困难。代码库需要有关于如何设置的最新指南,理想情况下,它应该包含两个步骤:

  1. 设置环境变量。
  2. 运行单个命令。

任何超出这两个步骤的事情都必须得到绝对保证。

在我工作的一家公司中,我们开发了最有雄心的企业软件。从开始到完成只用了四个小时,这是一个奇迹。这导致人们不愿部署或进行更大的更改,进而导致发布速度变慢、质量检查滞后,迭代速度非常慢。

此外,你希望确保程序不仅能启动,而且能以良好的状态启动。我已经数不清多少次因为缺少 API 密钥,运行 React 应用程序时看到损坏的页面。

使用架构验证库来检查你是否拥有所有必要的环境变量,阻止应用程序启动或确保它不会因缺失数据而损坏。

这适用于任何应用程序,无论是 SPA、REST API 还是其他。

准备一个“实时”环境

只要您正在处理的产品必须位于您自己的机器之外,您就必须在设置存储库的那一刻准备一个实时环境。即使只是一个实验,只要你需要一些类似生产的地方来部署它,最好早点创建它。

对于新项目,一个大问题是它们可能围绕本地环境的细节构建——环境变量、构建过程细节和运行时版本。通过将本地设置(无论是否使用容器)与“生产”同步,你可以确保避免以后面对晦涩的问题。

假设你的提供商不支持最新的 Node 版本,而你在工作中使用了新的标准库函数,你将不得不重构。或者你卡在一个旧版本的库中,无法在更新的环境中运行。你将不得不更新,从而导致更多重构,或者重新考虑提供商选择。

更不用说,如果你的代码在两个不同环境中运行,出现奇怪错误的概率更高。所以越早将本地开发状态与生产同步越好。

轻松部署

快速迭代功能并发布错误修复对软件产品的质量至关重要,而这只能通过简化的部署过程来实现。

部署过程越复杂,你就越不愿频繁进行。这不仅耗费大量时间,还带来情感上的阻力。复杂的手动部署会成为你不断推迟的那种耗时任务。

频繁部署意味着你会向生产环境推送较小的更改。这样问题发生的几率更低,即使出现问题,回滚也更容易。你要测试的功能也会减少,相应的 QA 工作量减少,且如果你的 PR 不涉及 30 个文件,审查速度也会快得多。

你将能够更加专注于开发功能和提高产品质量。

反对频繁部署的人通常会担心稳定性。他们认为不能把不成熟的功能给用户使用,有时候一次需要更改 30 个文件才能让功能工作。

但请记住,生产中的功能并不一定要向用户开放。

你使用的大部分软件产品都具备功能标志,它们可以向用户隐藏或关闭应用程序的某些部分,但这些部分仍然存在于代码库中。虽然这本身是一个相当复杂的项目,但一个简单的环境变量就足以检查是否应启用某个功能。

理想情况下,你希望在存储库的主分支中进行推送,以触发完全或至少半自动化的部署。

减少环境数量

在本章中,我们的目标是尽可能简化部署过程。一项重要因素是环境的数量。

每个环境都需要维护——生产环境是显而易见的,但暂存环境必须尽可能接近生产环境才能有用,而开发环境需要保持稳定状态。

但这需要大量维护工作。

我的理念是将环境数量减少到最低限度,提供必要的安全性。在我的理想世界中,应该只有两个环境——本地(local)和生产(prod)。除非有非常好的理由,否则不应增加更多环境。

测试拉取请求的短期环境是可以的。但长期存在的环境需要提供保障或解决问题,否则只会增加额外步骤而无益处。在关键领域工作的公司需要多种环境,以便在现实中测试他们的服务。

但小企业从更长的生产路径中几乎得不到任何好处。

支持多存储方法

当我们需要在多个相关组件之间共享功能时,Monorepos 非常有用。我们可以单独部署它们,但让它们共存可以消除对共享库的需求,并使彻底的更改更容易。

但它们会将你的 CI/CD 技能推向极限。

你需要处理标记和其他 monorepo 工具,增加了额外复杂性,以避免重复逻辑。

这会导致更困难的部署,这是一个不轻松的权衡。更简单、更稳定的部署为团队提供的价值远超在项目之间共享类型的便利。

此外,多存储库方法迫使你从不同的服务和组件的角度审视产品,贴近它们在生产中的行为方式。这让你更好地考虑向后兼容性,并以更自然的方式进行更改。

这一切都值得吗?

在第三章中,我们没有写过一行代码,只是在一个无休止的设置阶段,事情越来越多。但请记住,软件工程是关于构建产品,而不是在 IDE 中编写代码。

谷歌说,编程是让计算机执行你想要的任务的行为。编写算法是编程的一例。软件工程是在较长时间跨度内维护编程解决方案。

我们从事的是软件工程。

某些时候,我们必须做上述所有事情。如果在没有这些额外步骤的情况下开始开发,将在未来的重构中增添更多工作。这些问题堆积,导致项目陷入不良状态。

代码库更多是因为许多小错误而降级,而不是一个大错误。

为避免这种情况,我们可以先问自己:“如何确保它尽早投入生产?” 我们讨论的所有内容也适用于现有项目。


泯泷
34 声望3 粉丝