好的書本分章節、好的代碼分模塊,那麼好的架構該如何定義呢?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】 |
---|---|
![]() |
![]() |