likes
comments
collection
share

有意义的前端应用程序文件夹结构

作者站长头像
站长
· 阅读数 12

微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势,学习途径等等。 本文 GitHub github.com/qq449245884… 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

快来免费体验ChatGpt plus版本的,我们出的钱 体验地址:chat.waixingyun.cn 可以加入网站底部技术群,一起找bug,另外新版作图神器,ChatGPT4 已上线 cube.waixingyun.cn/home

对于大规模应用来说,最关键也最具挑战性的方面之一就是良好且合理的文件夹结构。在考虑将代码库分解为使用微前端的多个应用之前,有一些步骤可以遵循,以在项目级别改进架构,并使过渡更加容易,如果你曾经考虑过这条路径的话。

目标是应用某种模块化,通过在功能之间设定边界并最小化代码耦合和副作用,使代码库更易于理解。

默认项目结构

默认情况下,当使用某个流行的前端框架搭建新项目时,组件结构是平坦的,完全不遵循任何层次结构。

有意义的前端应用程序文件夹结构

  • assets 目录用于存储整个应用程序中使用的静态资源,如图片、字体和CSS文件。
  • components 目录包含可重用的Vue组件,建议使用扁平化的层次结构。
  • main.js 文件作为应用程序的入口点,使得 Vue 初始化和插件或附加库的配置成为可能。
  • App.vue 文件代表了我们应用程序的根组件,它充当其他组件的容器,并作为主模板提供服务。

我们已经深刻体验到,对于大型项目来说,这种架构很快就会失控。我们需要某种模块化,以便能够轻松定位特定文件,设定功能之间的边界,并避免组件之间的紧密耦合。

将应用程序分解为多个功能

任何大型应用程序都会被拆分为多个独立的功能。识别它们并不总是容易和直接的,但随着时间和经验的积累,这个过程会变得更好。让我们一起尝试将一个流行的应用程序分解为各个部分作为练习。

有意义的前端应用程序文件夹结构

推特的主页内容丰富多彩。页面的核心部分是时间线,周围围绕着许多功能,如导航、推文创建区域、带有多个子组件的侧边栏、浮动消息组件等等。

将构成这些功能的所有组件放在同一个文件夹中是无法维护的,即使使用IDE的快速查找选项,要找到其中的一个也会非常困难。

一个更详细的项目结构

根据经验,一个更好且更全面的文件结构应该是这样的:

有意义的前端应用程序文件夹结构

  • components : 所有在整个应用程序中使用的共享组件。
  • composables : 所有共享的可组合部件。
  • config : 应用程序配置文件。
  • features : 包含所有的应用程序功能。我们希望将大部分的应用程序代码保留在这里。
  • layouts : 页面的不同布局。
  • lib : 我们应用中使用的各种第三方库的配置。
  • pages : 我们应用程序的页面。
  • services : 共享的应用服务和提供商。
  • stores : 全局状态存储。
  • test : 与测试相关的模拟、助手、实用程序和配置。
  • types : 共享的 TypeScript 类型定义。
  • utils : 共享的实用功能。

需要注意的三件重要事项:

  • Pages 文件夹本身就已经在一定程度上实现了模块化,无论是在上下文方面还是在像webpack或Vite这样的构建工具会创建的实际块方面。将所有页面放在一个地方非常有帮助,但是它们内部的逻辑应该尽量简化。
  • 为了更便于维护和扩展,我们的目标是将大部分应用程序代码保留在 features 文件夹内。每个功能文件夹应包含给定功能的特定领域代码。
  • 在理想的世界里,我们不应该有共享的组件、可组合的、存储和服务,所有的东西都应该在相应的特性文件夹内。不幸的是,在实际的项目中,这是无法避免的,但我们应该提前规划,并在向这些文件夹添加内容时格外小心

Features Folder 功能文件夹

正如我们之前提到的,我们的应用程序的大部分应该存在于特性文件夹中,并分割成多个子目录。

有意义的前端应用程序文件夹结构

  • api : 所有的获取逻辑都在这里,这使得API和UI解耦。
  • components : 特定功能的组件。
  • composables : 特定功能的可组合项。
  • stores : 状态管理代码,我们期待并实际上鼓励有多个子模块。
  • types : 特定功能的TypeScript类型定义。
  • index.ts : 这是功能的入口点。它作为功能的公共API进行操作,只应导出应用程序的其他部分应公开的内容。

上述的 index.ts 文件作为每个功能的公共API。当从另一个领域导入某些内容时,应仅通过此文件进行。这应该可以防止循环依赖,并且也使得找到导入源更为容易。

# Bad 🚫 🚫 🚫
import { UserProfile } from '@/features/profile/components/UserProfile.vue'

# Good ✅ ✅ ✅
import { UserProfile } from '@/features/profile'

我们可以通过使用 no-restricted-imports ESLint规则来执行这种模式。

rules: {
    'no-restricted-imports': [
      'error',
      {
        patterns: ['@/features/*/*'],
      },
    ],
    'import/no-cycle': 'error',
    ...
}

总结

以特性为导向的架构是组织复杂项目的有效且经过实战检验的方式。它使我们能够将代码解耦为独立的模块,并随着应用程序变得更复杂而扩展。这将通过提高代码库的可预测性,减少调试时间并使新员工入职更容易,从而提升开发体验。

交流

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub github.com/qq449245884… 已收录,有一线大厂面试完整考点、资料以及我的系列文章。