好的书本分章节、好的代码分模块,那么好的架构该如何定义呢?css
咳咳,不要意思,题目起大了~~ 小生之辈,岂敢以架构而论。前端
不过话说来,不少人都认为前端无非就是 HTML
+CSS
+JS
,一个目录一类文件,有何架构可言。可是我想说。。。。你说的都对!react
可是,笔者一直在探索不一样的页面架构组织形式,鄙人愚见,好的架构,可以方便拓展和开发以及后期的项目维护。git
在笔者刚开始接触前端的时候,就一直在思考怎么样的架构比较舒服易于扩展,且能装 B。React-Full-Dianping-Demo里面就有写到对于react
+react-redux
+soga
的一些列代码组织的思考:react技术栈项目结构探究github
一直还在学习,本文也只是拿来探讨下本次我开发一个页面时,我我的的一些代码组织方式。抛个砖~json
望各位大佬不啬赐教。redux
src
├─ action-log
│ ├─ constants.ts
│ └─ index.ts
├─ app.js
├─ app.json
├─ common
│ ├─ animation-utils.ts
│ ├─ business-utils.ts
│ ├─ constants.ts
│ ├─ detail-utils.ts
│ ├─ mtop-utils.ts
│ ├─ net-utils.ts
│ ├─ price-utils.ts
│ ├─ storage-utils.ts
│ ├─ string-utils.ts
│ ├─ time-utils.ts
│ ├─ type.ts
│ ├─ url-utils.ts
│ └─ utils.ts
├─ components
│ ├─ loading-page
│ │ ├─ index.css
│ │ └─ index.tsx
│ └─ pm-bottom
│ ├─ index.css
│ └─ index.tsx
├─ document
│ └─ index.jsx
├─ event
│ └─ EVENTS.ts
├─ modules
│ ├─ bottom-action
│ │ ├─ index.css
│ │ └─ index.tsx
│ └─ page-container
│ ├─ base
│ ├─ decorator
│ ├─ index.tsx
│ └─ libs
└─ pages
├─ buyer-identity
│ ├─ components
│ ├─ constants
│ ├─ customized-hooks
│ ├─ index.tsx
│ ├─ types
│ └─ utils
复制代码
或许上面看起来并非很直观,截图解释下api
大概的看下,脑海中有个大概的位置和每一个文件的做用。下面咱们再来细品bash
其实划分了这么多的目录,无非就是为了最大可能的复用。其中也包括对于组件状态的抽离、hooks 特性的利用。微信
毕竟是MPA
应用,因此一切还都是围绕着 pages
展开。
首先这里的action-log
目录就很少说了,由于没有太多可借鉴性。大概就是返回一个 ActionLog
对象,来进行一些业务上的埋点、信息收集等逻辑的处理。因此这里若是你们有一些公共的基础类封装,都是能够放这里的。
common
├─ animation-utils.ts
├─ business-utils.ts
├─ constants.ts
├─ detail-utils.ts
├─ mtop-utils.ts
├─ net-utils.ts
├─ price-utils.ts
├─ storage-utils.ts
├─ string-utils.ts
├─ time-utils.ts
├─ type.ts
├─ url-utils.ts
└─ utils.ts
复制代码
因为该项目的比较复杂,业务逻辑相对较多。因此这里我将 utils
按照类别,区分出来了以上几种。方面后期开发中的维护和扩展,也便于查找。
除了一些从命名能够区分出来的utils
之外,这里还放了一个 type.ts
和constants.ts
,用途自如其名。
相信框架使用者对于 components
的命名都不为陌生.是的,就是对于一些公共组件的封装,好比我这里放的两个组件loading-page
,pm-bottom
等公共组件。components 相对来讲是比较“小”的概念,划分依据这这个项目中也比较简单,就是是否为“木偶组件”(虽然 hooks 了之后,咱不太适合这么说),
modules
├─ bottom-action
│ ├─ index.css
│ └─ index.tsx
└─ page-container
├─ base
│ ├─ base.tsx
│ ├─ error.tsx
│ └─ scrollBase.tsx
├─ decorator
│ └─ withError.tsx
├─ index.tsx
└─ libs
├─ displayName.ts
├─ navbarTransparent.ts
├─ spm.ts
└─ title.ts
复制代码
更具备模块的概念,这里最典型的page-contaienr
的模块,做用就是每个页面的通用底层容器,早在以前的文章中其实有介绍到这个容器,如何用 Decorator 装饰你的 Typescript,因此这里就再也不赘述了,其实就是一些基础功能的封装。因此也就是解释了event
的目录存在。
而这里modules
和conponents
最大的区别就是,复杂度和内部状态管理。若是内部状态较为复杂,且有不少的交互,那么咱们就称之为 module
.是的,这里的界限,咱们划分较为模糊。
可是当你拿到一份设计稿的时候,估计就能明白个人良苦用心了~
红色框就能够理解为 module,绿色框能够理解为 components
针对单个页面里面的组织,其实都大同小异。(忽然发现前端架构没有太多可言)
目录区分的并非不少,可是也都较为清晰。简单介绍下每一个区域的分工,须要展开的,咱们在后续展开介绍
index.tsx
页面的入口文件,可是自己里面不会编写太多业务逻辑utils
该页面的工具函数,包括接口的请求、数据的 format
等customized-hooks
自定义hooks
,这里有两个,初始化 UI 所须要的数据(边距等),业务请求的数据。constants
页面的常量,包括请求的 api
、spm
埋点、固定的一些该页面业务数据等components
该页面的组件(注意这里没有 module,由于太多了真的容易混乱),页面的 components
,有简单的,也有复杂的。以上就是一些目录结构和代码组织的交代。其实仍是比较简单清晰的。下面介绍下
碎碎叨叨道不到个明明白白
由于是业务代码,因此这里就不会粘贴太多代码了
简单的解释下上面的流程
初始化 UI 的逻辑比较偏于业务,其实没有太多可借鉴的。这里我代码里面的工做也就是适配 iPhone X
的一些UI。
重点说下初始化接口数据的过程吧。其实也就是各个页面中的 components
的状态初始化
首先咱们须要定义每个模块的 props
,毕竟是由于用的 ts
,注释即文档。因此咱们将每个 components
的 props
都定义到 type
目录中,毕竟不少时候接口返回的数据,须要咱们作一次 format
,而这个 format
的目的就是为了 components
更好的使用。换句话说,这些接口,可复用! 那必然定义到外面
注意接口上都要写注释啊!!!!理由以下:
将全部数据处理的方法,所有放到 utils
中(注意数据兜底的处理,这里我全部的数据处理都写好工具函数,并添加充分的单元测试)
真正的作到对 components
而言,开箱即用。
由于有 type
的定义和 components
之间的约束,因此不管是componemts
内部的数据使用仍是 index.tsx
里面的模块引入时 props
的注入,都有很好的约束
编写时候的提醒
漏写时候的报错
因为咱们使用了 hooks
,且相对隔离的组件划分,原则上,组件通讯其实并非不少。固然,也必然是有的。
其实这方面的约束主要归结于业务的复杂度,若是数据逻辑比较复杂,且通讯较多。那么能够考虑使用 useContext
和 useReducer
说下此次需求中涉及到的通讯。
原则:组件尽量值管理本身的状态。
遵循如上原则,最终的业务交互逻辑都是由组件内部管理,涉及到的同级通讯则经过父组件操做。而父组件操做的原则就是只拿数据,不作任何业务处理。(尽量的撇清关系)
index
尽量不写业务逻辑hooks
component
过于复杂需额外抽离 component
、 utils
和 customized-hooks
等。参照上文component
的 props
需抽离复用utils
方法编写充分的单元测试utils
的方法导出需单独导出(bundle
大小),且编写注释(调用时候的提醒)interface
,而且编写注释.毕竟注释即文档以上约束后期应该都会编写相应的 Eslint
来进行强约束(咳咳,程序猿基本素养不可靠)
最后看下我正在补充的单元测试,编写单元测试过程当中,的确发现了很多工具函数的边缘状况处理的有问题
按照如上的 page
代码组织后面又写了一个页面,感受代码的组织和状态的管理仍是较为清晰的。后续会编写相应的 cli 来自动生成页面基础架构,好比 pmCli add page
or pmCli add com
由于本文不方便粘贴太多代码,因此可能说的有些云里雾里,有任何疑问,欢迎公众号内回复【1】,加入全栈技术交流③群,一块儿交流
最后,本文只作一个抛转,并不是定义一种规范。更多的约束和组织,但愿你们多多交流,互相学习。
公众号【全栈前端精选】 | 我的微信【is_Nealyang】 |
---|---|
![]() |
![]() |