大家好,我是Kason。React技术栈的优势之一就是社区繁荣,你在业务中需要实现的功能基本都能找到对应的开源库。但繁荣也有不利的一面——实现同样的功能,选择太多,该选哪个?本文将介绍一个12.7k的开源项目——BulletproofReact[1]。该项目对构建“干净、强大、可扩展的前端项目架构”的各个方面给出了建议。什么是防弹反应?BulletproofReact不同于我们常见的脚手架(比如CRA),它的作用是“根据模板创建一个新项目”。前者包括一个完整的React全栈论坛项目:用户登录页作者以该项目为例,展示了与“项目架构”相关的13个方面,例如:如何组织文件目录。推荐的工程配置是什么。编写业务组件时如何规范。如何进行状态管理。API层如何设计。etc.......由于篇幅有限,本文介绍了其中的一些。你同意这些观点吗?文件目录如何组织项目推荐如下目录格式:src|+--assets#静态资源|+--components#公共组件|+--config#全局配置|+--features#特性|+--hooks#公共钩子|+--lib#二次导出的第三方库|+--providers#应用中的所有provider|+--routes#路由配置|+--stores#全局statestores|+--test#测试工具,mockServer|+--types#全局类型文件|+--utils#通用工具功能其中features目录和components目录的区别在于components存放的是全局公共组件,而features存放的是"业务相关的功能”。比如我要开发“评论”模块。“评论”是一个特征,所有和它相关的内容都存在于features/comments目录下。“评论”模块中需要输入框,输入框的通用组件来自components目录。所有“特性相关”的内容都会汇聚到features目录下,包括:src/features/xxx-feature|+--api#特性相关的请求|+--assets#特性相关的静态资源|+--components#componentsrelatedtofeatures|+--hooks#hooksrelatedtofeatures|+--routes#routesrelatedtofeatures|+--stores#statestoresrelatedtofeatures|+--types#relatedtofeatures相关类型声明|+--utils#Feature相关的实用函数|+--index.ts#入口特征导出的所有内容只能通过统一入口调用,例如:import{CommentBar}from"@/features/comments"改为:import{CommentBar}from"@/features/comments/components/CommentBar这可以通过配置ESLint来实现:{rules:{'no-restricted-imports':['error',{patterns:['@/features/*/*'],},],//...其他配置}}与在全局目录中以“平面形式”存储“功能相关内容”相比(例如,存储功能钩子存放在全局hooks目录下),将features目录作为“相关代码的集合”,可以有效防止项目规模增大后代码组织混乱。怎么做?并不是状态管理项目中的所有状态都需要存储在“中心化存储”中,需要根据状态类型区别对待。组件状态对于组件的局部状态,如果只有组件本身及其后代需要这部分状态,可以用useState或useReducer保存。应用状态的状态与应用交互的状态有关,比如“打开弹窗”、“通知”、“改变深色模式”等,应该遵循“放状态”的原则尽可能靠近使用它的组件”,并且不要将所有状态都定义为“全局状态”。以BulletproofReact中的示例工程为例,首先定义“通知相关状态”://bulletproof-react/src/stores/notifications.tsexportconstuseNotificationStore=create
