前端架构设计(可扩展性的前端架构)

可扩展性的前端架构⚠️

可能你有一个想法在你的脑海中敲打,并且想知道实现它的最佳方法。不要着急,不要着急!不要立即开始编写代码。如果你有一个项目想法,无论是从它开始一家公司,还是向雇主或招聘人员展示它,都需要正确地完成它,考虑可扩展的架构是一个很好的开始方式。让我们深入挖掘!

前端架构设计(可扩展性的前端架构)(1)

我们所说的“架构”是什么意思?

当然,我们去维基百科看看定义:

软件架构是指软件系统的基本结构以及创建此类结构和系统的学科。每个结构都包含软件元素、它们之间的关系以及元素和关系的属性。

是的,我知道你可以自己完成,但你没有。让我们把这个定义分解成碎片,自然地,给出我的意见!

对我来说,架构的定义取决于范围,取决于你看到系统的“缩放”。它可能意味着如何将系统构建为一个整体,包括前端、后端和数据库;它可能意味着如何组织微服务通信......但在我们的例子中,我们将放大并只查看前端范围,这已经足够了,相信我。

前端架构考虑选择正确的技术堆栈(在我们的例子中它已经被选择,我稍后会向你解释为什么),构建我们的项目文件,并建立它们之间的通信。

为什么我们需要前端架构?

如果你达到了这一点,你可能想知道为什么?为什么!?好吧,让我回到我的第一段来解释。想象一下,你开始了一个出售二手物品的项目。您的 MVP 包括使用他们的电话号码创建用户帐户,这些用户帐户可以发布带有照片、描述和价格的产品。然后你去市场,你的客户开始使用你的平台,并要求你加入聊天。您的投资者想向您的全新创业公司投入资金,但首先,他们需要您包括类别和搜索栏。然后你做一些市场调查,发现你可以与现有的汽车制造商合作销售他们的二手车,但你需要将它们与你的用户已经在你的应用程序中销售的其他产品区分开来。你没看到这越来越病态了吗?你没看到我想去哪里吗?

最好的部分是每个人都会设定最后期限,你的投资者、你的用户、你的合作伙伴……如果你的代码库还没有准备好处理这些新功能,你的创业公司就死了。

你怎么能避免这种情况?好问题,通过在开始编码之前思考,确定如何组织代码、如何管理信息以及软件的不同部分将如何通信。

我们什么时候需要考虑前端架构?

我会说您应该始终考虑它,因为它会使您成为更好的开发人员。但是,如果项目解决了一个小的具体问题,并且您确定它不会更进一步(瀑布),那么这并不重要,您可能可以更快地交付项目而不会产生任何负面影响。

我们为什么选择 Next.JS?

这是一个很好的问题,答案很简单。Next.JS 是一个很棒的框架,用于启动项目并使其随着时间的推移而增长。它很容易启动,无需太多配置。它为您提供所有 React.JS 的强大功能,包括类固醇、混合静态和服务器渲染、TypeScript 支持、智能捆绑、路由预取等。此外,如果您的项目需要后端支持,可以在 Next.JS 生态系统中轻松开发。当项目增长并需要其后端甚至微服务时,现有代码可以通过其 API 轻松移动到快速服务器。够了吗,还是需要更多?它对 SEO 友好,易于部署,与其他技术配合得很好,有很好的文档,以及它背后的所有 React 社区。

Next.JS 看起来不错?

正如我在上一段中告诉你的,Next.JS 与许多技术配合得很好,并根据我们的需求选择合适的技术,这是我们成功架构的关键。无论如何,我们应该始终选择具有良好社区支持的稳定库和包,以防遇到任何问题。

打字稿

走向高可扩展性几乎等于说我们需要选择某种类型的语言,牺牲一些时间键入我们的代码可以避免将来花费时间、金钱和精力来寻找错误。

顺风

样式是前端开发的重要组成部分,我们应该注意它,但不要花太多时间在设置、维护或处理很多不同的屏幕尺寸上……因此,样式库可以做一些工作。但是,添加组件库并不是解决此问题的最佳方法,因为我们无法完全控制我们的产品,并且我们将来会受到它的影响。

我建议您拥有自己的组件库,最好在单独的存储库中并通过npm安装。但是,一开始这可能很乏味,因此我们将设置我们的文件夹结构以在将来简化此过程。

Tailwind 是为我们的组件设计样式的绝佳解决方案,因为它让我们可以轻松地自定义每一行 CSS,使用已定义的类名或在默认类名之上创建我们自己的类名并将它们与 CSS 模块一起使用。

反应钩子形式

如今,一个典型的 Web 应用程序将有一些表单,这些表单需要通过验证和对后端的调用以最简单的方式进行处理。我发现使用 react-hook-forms 库使这个过程更容易,因为它为我们提供了在后台为我们处理大量逻辑的钩子。

反应查询

稍后我们将看到组织 API 调用的最佳方法,但我们需要像 React Query 这样的库来为我们处理缓存。缓存可能对我们的最终应用程序产生重要的经济影响,通过减少后端调用来节省成本,并从例如按请求计费的 s3 存储桶提供图像。

埃斯林特和更漂亮

我们信心十足的 linter 和代码格式化程序。他们来这里是为了让我们的工作更轻松。使用 linter 的目的是展示不良做法、潜在错误和风格错误。并结合一个好的格式化程序,例如 prettier,我们可以确保我们团队的每个成员都在同一个页面上,具有相同的代码风格。在同一个代码库中与多个人一起工作时,一些拉取请求显示更多关于格式问题的更改是很常见的,因为编辑器格式化程序更改了一些代码行(制表符、介绍、空格、括号......),这可以因开发人员而异。这样,我们确保每个人都遵循相同的规则,最好的事情是这两种技术都可以轻松地集成到我们的代码编辑器中。

尽管拥有一个 linter 和一个格式化程序可能有助于交付高质量的代码,但我们可以使用更多技术来改进这个过程。我想到的第一个是使用目录别名进行绝对导入。为什么我们应该使用../../../../filename而不是@directory/filename?通过向 tsconfig.json 文件添加一些别名并创建,这是一个非常愚蠢且易于实现的更改。

如何组织代码以实现潜在增长

在我的专业经验中,我见过一些项目没有投入时间来设置文件夹结构和组件之间的数据流,最终变得一团糟。代码应该自己说话,你应该能够毫无疑问地找到任何东西。这是通过良好的文件夹结构以及一致的命名约定来完成的。

分而治之
  • 成分。经典,对吧?每个基于 React 的项目都有这个文件夹,但问题是里面有什么。在大多数情况下是混乱所在。对我来说,它至少应该有以下子文件夹:- Ui。所有基本组件,界面的最小组件都应该在这个文件夹中,可以将其导出到新的存储库,并在以后上传到像 npm 这样的包管理器。-布局。根据您的路线,您的 Web 应用程序可能具有不同的布局。例如,您可能有一个主页布局和一个仪表板布局,这取决于您是否登录。所有这些布局都应该在这个文件夹中。-与页面相关的组件。假设您有一个产品页面,其中包含仅在产品页面上下文中有用的ProductGrid组件。然后你应该在 components 目录中有一个名为 products 的文件夹,里面有这个组件。当然,ProductGrid将使用ui和 products 文件夹中的组件。-部分。不同布局或页面共有的所有组件,例如页眉和页脚,但不是通用的将它们导出到一个公共包,都应该放在这个文件夹中。这些组件应该构建在ui文件夹中的组件之上,但它们被许多与页面相关的组件使用。-搜索引擎优化。我喜欢为我将在我的页面中使用的 SEO 组件创建一个页面。-上下文。将您的上下文提供程序和访问它们的钩子放在这里。
  • 库。在这个文件夹中,我处理应用程序本身的所有逻辑。国际化,用于跨组件和常量重用某些逻辑的挂钩。
  • 阿皮。当然,这个文件夹将包含所有后端调用和服务,最好使用钩子来创建请求(React Query)。我按域划分它们。按照前面的示例,与产品相关的 CRUD 操作将进入api/products。
  • 上市。所有媒体:照片、视频、字体、图标。
  • 风格。通常很傻,但我在其中添加了顺风风格。
  • 语言环境。JSON 文件,包括应用程序涵盖的所有语言的翻译。
  • 页。在生成 Next.JS 项目时提供,它将包含 Web 应用程序中的不同路由。我建议您在 URL 本身中设置一个国际化系统。这可以通过创建一个名为[locale] 的文件夹轻松完成。然后,您可以创建一个可以访问路由查询并从 URL 获取语言的 Provider。这可以在另一篇带有代码示例的文章中介绍。
  • .prettier、.eslintrc、nextjs.config.js、tailwlind.config.js等配置文件位于顶级文件夹中。
你应该遵循的反应模式

这部分可以单独写一篇文章,所以我只会在开始时说两件重要的事情,并在未来用另一篇文章扩展这个主题。

如何管理您的应用程序状态

简而言之,本节将介绍如何在应用程序的组件之间进行数据通信和共享。本节不会涵盖从父级传递给子级的简单道具。直截了当地说,全局应用程序状态管理有两个选项。要么使用Redux之类的状态管理库,要么坚持使用 React 库中已经包含的 React Context API,它可以很容易地与 hooks 结合来启动它。

Redux 适用于具有动态数据的大型应用程序,并在 UI 和状态管理逻辑之间建立了分离,这非常好。但是,您必须牺牲代码的可读性和时间(尤其是在开始时,因为它需要大量的设置时间)。所以,这是一个权衡,如果你需要处理一个相当复杂的状态,需要考虑很多事情,比如一个交易应用程序,它需要处理股票的实时数据,同时让你绘制图表并创建数据的可视化表示,使用像 Redux 这样的全局状态管理工具是必不可少的。

如果上述情况不适用于您的项目,您可能应该选择 Context API,它将产生更易读和可维护的代码,更少冗长,并且没有不必要的复杂性。

无论如何,由于我们正在考虑您的应用程序的巨大潜在增长,假设您开始使用 Context API 处理全局状态,突然您需要使用 Redux 更容易处理的解决方案,您可以创建一个使用 React 本身提供的 Context API 和 useReducer 挂钩进行存储(此处链接到如何执行此操作的教程)。

我们什么时候需要抽象逻辑?

这很简单,请阅读Robert Martin 的 The Clean Code。然后你会看到很多很明显的事情,但你没有做。例如,在我必须抽象其逻辑之后,需要重复多少次代码片段?剧透警报,不止 2 个。只要您遵循两个原则,DRY(不要重复自己)和 KISS(保持简单傻),一切都会好起来的。懒一点,你写的代码越少,你发现的错误就越少,你需要维护的也就越少,这就是你将获得的生活质量。

参考
  • 软件架构定义
  • Next.JS 功能
  • Next.JS 与 Typescript
  • 反应钩子形式
  • 顺风
  • 埃斯林特
  • 更漂亮
  • 干燥和亲吻
,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页