一张页面引起的项目架构思考(Rax+Typescript+hooks)
前言
好的书本分章节、好的代码分模块,那么好的架构该如何定义呢?
咳咳,不要意思,题目起大了~~ 小生之辈,岂敢以架构而论。
不过话说来,很多人都认为前台无非就是 HTML+CSS+JS,一个目录一类文件,有何架构可言。但是我想说。。。。你说的都对!
image
但是,笔者一直在探究不同的页面架构组织形式,鄙人愚见,好的架构,能够方便拓展和开发以及后期的项目维护。
在笔者刚开始接触前台的时候,就一直在思考怎样样的架构比较舒服易于扩展,且能装 B。React-Full-Dianping-Demo里面就有写到对于react+react-redux+soga的少量列代码组织的思考:react技术栈项目结构探索
一直还在学习,本文也只是拿来讨论下本次我开发一个页面时,我个人的少量代码组织方式。抛个砖~
望各位大佬不啬赐教。
image
项目架构
image
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或者许上面看起来并不是很直观,截图解释下
image
image
大概的看下,脑海中有个大概的位置和每个文件的作用。下面我们再来细品
目录职责
其实划分了这么多的目录,无非就是为了最大可能的复用。其中也包括对于组件状态的抽离、hooks 特性的利用。
pages 层以外的公共逻辑
毕竟是MPA应用,所以一切还都是围绕着 pages 开展。
action-log
首先这里的action-log目录就不多说了,由于没有太多可借鉴性。大概就是返回一个 ActionLog对象,来进行少量业务上的埋点、信息收集等逻辑的解决。所以这里假如大家有少量公共的基础类封装,都是可以放这里的。
common
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
相信框架使用者对于 components 的命名都不为陌生.是的,就是对于少量公共组件的封装,比方我这里放的两个组件loading-page,pm-bottom等公共组件。components 相对来说是比较“小”的概念,划分依据这这个项目中也比较简单,就是能否为“木偶组件”(尽管 hooks 了以后,咱不太适合这么说),
modules
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.是的,这里的界限,我们划分较为模糊。
但是当你拿到一份设计稿的时候,预计就能明白我的良苦用心了~
image
红色框即可以了解为 module,绿色框可以了解为 components
page 的组织
针对单个页面里面的组织,其实都大同小异。(忽然发现前台架构没有太多可言)
image
目录区分的并不是很多,但是也都较为清晰。简单详情下每个区域的分工,需要开展的,我们在后续开展详情
index.tsx页面的入口文件,但是本身里面不会编写太多业务逻辑utils该页面的工具函数,包括接口的请求、数据的format等customized-hooks自己设置hooks,这里有两个,初始化 UI 所需要的数据(边距等),业务请求的数据。constants页面的常量,包括请求的api、spm埋点、固定的少量该页面业务数据等components该页面的组件(注意这里没有 module,由于太多了真的容易混乱),页面的components,有简单的,也有复杂的。
image
以上就是少量目录结构和代码组织的交代。其实还是比较简单清晰的。下面详情下
页面数据流向和管理规则
碎碎叨叨道不到个明明白白
image
由于是业务代码,所以这里就不会粘贴太多代码了
简单的解释下上面的流程
初始化 UI 的逻辑比较偏于业务,其实没有太多可借鉴的。这里我代码里面的工作也就是适配 iPhone X的少量UI。
重点说下初始化接口数据的过程吧。其实也就是各个页面中的 components 的状态初始化
interface
首先我们需要定义每一个模块的 props,毕竟是由于用的 ts,注释即文档。所以我们将每一个 components 的 props 都定义到 type 目录中,毕竟很多时候接口返回的数据,需要我们做一次 format,而这个 format 的目的就是为了 components 更好的使用。换句话说,这些接口,可复用! 那必然定义到外面
image
注意接口上都要写注释啊!!!!理由如下:
image
image
将所有数据解决的方法,一律放到 utils 中(注意数据兜底的解决,这里我所有的数据解决都写好工具函数,并增加充分的单元测试)
image
真正的做到对 components 而言,开箱即可使用。
由于有 type 的定义和 components 之间的束缚,所以无论是componemts 内部的数据使用还是 index.tsx 里面的模块引入时 props 的注入,都有很好的束缚
image
编写时候的提示
image
漏写时候的报错
组件通信
因为我们使用了 hooks,且相对隔离的组件划分,准则上,组件通信其实并不是很多。当然,也必然是有的。
其实这方面的束缚主要归结于业务的复杂度,假如数据逻辑比较复杂,且通信较多。那么可以考虑使用 useContext 和 useReducer
说下这次需求中涉及到的通信。
准则:组件尽可能值管理自己的状态。
遵循如上准则,最终的业务交互逻辑都是由组件内部管理,涉及到的同级通信则通过父组件操作。而父组件操作的准则就是只拿数据,不做任何业务解决。(尽可能的撇清关系)
束缚
index尽可能不写业务逻辑- UI 初始化和模块数据初始化需自己设置
hooks - 状态尽可能抽离。
component过于复杂需额外抽离component、utils和customized-hooks等。参照上文 component的props需抽离复用- 公共
utils方法编写充分的单元测试 - 公共
utils的方法导出需单独导出(bundle大小),且编写注释(调用时候的提示) - 尽可能定义
interface,并且编写注释.毕竟注释即文档
以上束缚后期应该都会编写相应的 Eslint 来进行强束缚(咳咳,程序猿基本素养不可靠)
最后看下我正在补充的单元测试,编写单元测试过程中,确实发现了不少工具函数的边缘情况解决的有问题
image
image
结束语
按照如上的 page 代码组织后面又写了一个页面,感觉代码的组织和状态的管理还是较为清晰的。后续会编写相应的 cli 来自动生成页面基础架构,比方 pmCli add page or pmCli add com
由于本文不方便粘贴太多代码,所以可能说的有些云里雾里,有任何问题,欢迎公众号内回复【1】,加入全栈技术交流③群,一起交流
最后,本文只做一个抛转,并非定义一种规范。更多的束缚和组织,希望大家多多交流,互相学习。
image
学习交流
- 关注公众号【全栈前台精选】,每日获取好文推荐
- 增加微信号:is_Nealyang(备注来源) ,入群交流
| 公众号【全栈前台精选】 | 个人微信【is_Nealyang】 |
|---|---|
image | image |
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 一张页面引起的项目架构思考(Rax+Typescript+hooks)
image
image