摘要:作為一個庫,它沒有規(guī)定項目的整體結(jié)構(gòu)。位于的組件應(yīng)命名為。組件根據(jù)其與組件或的相對路徑進(jìn)行相應(yīng)命名??紤]這樣一個場景,處于位置的組件會被命名為而不是。
React 作為一個庫,它沒有規(guī)定項目的整體結(jié)構(gòu)。這很好,因為它給了我們自由去嘗試不同的方法,并適應(yīng)更適合我們的方式。另一方面,這可能會給React領(lǐng)域的開發(fā)人員帶來一些困惑。
我將會在本文為大家展示我已經(jīng)使用過一段時間并且效果不錯的方式,這些方式?jīng)]有通過重新造輪子來實現(xiàn),而是通過將社區(qū)中的方案組合和提煉得到。
想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!
目錄結(jié)構(gòu)我經(jīng)常遇到的一個問題是如何組織文件和目錄結(jié)構(gòu)。在這篇文章中,我們認(rèn)為你已有一個最小的結(jié)構(gòu),就像用 create-react-app 創(chuàng)建的結(jié)構(gòu)一樣。
create-react-app 為我們生成了一個基礎(chǔ)的項目,包含根目錄還有諸如.gitignore, package.json, README.md, yarn.lock 的文件。
它還生成 public和src目錄, src目錄是我們保存源代碼的地方。
請看下面的圖片,以及描述的結(jié)構(gòu):
在這篇文章中,我們只關(guān)注src目錄,src 之外保持不變。
容器和組件 (Containers and Components)你可能已經(jīng)在某些項目的根目錄下看到了容器和展示組件之間的分離。我的意思是,在src中,在 src 目錄下有 containers 目錄和 components 目錄:
src ├─ components └─ containers
但是,這種方法有一些問題,如下所示:
主觀的規(guī)則:對于容器和展示組件,沒有明確的規(guī)則。彼此之間的差異可能是主觀的,當(dāng)你在一個團(tuán)隊中時,很難讓所有開發(fā)人員贊成并評判這個問題。
它沒有考慮組件的動態(tài)性:即使當(dāng)你決定某個組件適合于某個特定類型時,也很容易在項目生命周期中對其進(jìn)行更改,使其從另一種類型變?yōu)榱硪环N類型,最終迫使你把它從 components 挪到 containers 目錄下,反之亦然。
允許兩個具有相同名稱的組件:組件的命名在應(yīng)用程序中具有聲明性和惟一性,以避免混淆每個組件的職責(zé)。但是,上面的方式破壞了具有相同名稱的兩個組件,一個是容器,另一個是展示示組件。
效率低下: 即使你在實現(xiàn)一個獨立特性時,也不得不經(jīng)常在 containers 和 components 目錄下來回切換,因為一個獨立特性有兩種不同類型的組件是再正常不過的事情了。
還有一種方法,在模塊內(nèi)部保存containers和components分離:
src └─ User ├─ components └─ containers
上述方法最大限度地減少了在項目樹中不同層級目錄切換的問題。然而,它會增加很多噪音。根據(jù)你的應(yīng)用程序有多少模塊,你最終會創(chuàng)建幾十個containers 和components 目錄。
出于這些原因,當(dāng)我們談?wù)摻M織目錄和文件時,通過展示與容器的概念來拆分組件是無關(guān)緊要的。 也就是說,除頁面外,我們將把所有組件放在 components 目錄下。
即使在目錄上區(qū)分展示組件和容器組件是沒有太多必要的,了解它們之間的差異性依然是有必要的。如果你對這個話題還有疑問,建議閱讀這篇文章:Presentational and Container Components拆分和組合代碼
在components目錄中,我們按模塊/功能對文件進(jìn)行分組。
在用戶的增刪改查中,我們只有User模塊,結(jié)構(gòu)是這樣的
src └─ components └─ User ├─ Form.jsx └─ List.jsx
當(dāng)組件由多個文件組成時,我們將此組件及其文件放在具有相同名稱的目錄下。 例如:假設(shè)有一個包含Form.jsx樣式的Form.css。 在這種情況下,你的結(jié)構(gòu)如下:
src └─ components └─ User ├─ Form │ ├─ Form.jsx │ └─ Form.css └─ List.jsx
測試文件與被測試的文件保持一致。在上面的例子中,Form.jsx 的測試文件會放在同一個文件夾下并且命名為 Form.spec.jsxUI 組件
除了通過模塊拆分組件之外,我們還在src/components中包含一個 UI 目錄,以保留其中的所有通用組件。
UI 組件是通用的組件,不屬于模塊。 它們是可以保留在開源庫中的組件,因為它們沒有來自特定應(yīng)用程序的任何業(yè)務(wù)邏輯。 這些組件的示例包括:按鈕,輸入,復(fù)選框,選擇,模態(tài)框,數(shù)據(jù)可視化組件等等。
命名組件中的類上面我們看到了如何構(gòu)建目錄并按模塊分離我們的組件。 但是,還有一個問題:如何命名它們?
當(dāng)我們談?wù)撁M件時,它涉及我們給類或定義組件的常量名稱:
class MyComponent extends Component { } const MyComponent () => {};
如上所述,我們?yōu)榻M件提供的名稱應(yīng)該在應(yīng)用程序中清晰且獨特,以便更容易找到并避免可能的混淆。
當(dāng)我們需要使用工具作為React Dev工具進(jìn)行調(diào)試時,以及當(dāng)應(yīng)用程序中發(fā)生運行時錯誤時,組件的名稱非常方便,錯誤總是與發(fā)生錯誤的組件名一起出現(xiàn)。
我們采用基于路徑的組件命名方式,即根據(jù)相對于 components 文件目錄的相對路徑來命名,如果在此文件夾以外,則使用相對于 src 目錄的路徑。舉個例子,組件的路徑如果是 components/User/List.jsx,那么它就被命名為 UserList。
當(dāng)文件位于具有相同名稱的組件中時,我們不需要重復(fù)該名稱。 也就是說,components/User/Form/Form.jsx將被命名為UserForm而不是UserFormForm。
上面的模式有一些好處,我們可以在下面看到:
便于在項目中搜索文件如果編輯器支持模糊搜索,只需搜索名稱UserForm就可以找到正確的文件
如果你想要在目錄中搜索文件,可以很容易地通過組件的名字定位到它:
避免在導(dǎo)入重復(fù)名稱按照該模式,可以始終根據(jù)文件的上下文為組件命名??紤]到上面的表單,我們知道它是一個用戶表單,但是由于我們已經(jīng)在 User 目錄中 ,所以不需要在組件文件名中重復(fù)這個單詞。因此,我們只將它命名為Form.jsx。
我最初使用 React 的時候喜歡用完整的名字來命名文件,但是這樣會導(dǎo)致相同的部分重復(fù)太多次,同時引入時的路徑太長。來看看這兩種方式的區(qū)別:
import ScreensUserForm from "./screens/User/UserForm"; // vs import ScreensUserForm from "./screens/User/Form";
在上面的示例中,可能無法看到從一種方法到另一種方法的優(yōu)勢。 但是應(yīng)用程序名稱多了話,就可以看到差異, 如下:
import MediaPlanViewChannel from "/MediaPlan/MediaPlanView/MediaPlanViewChannel.jsx"; // vs import MediaPlanViewChannel from "./MediaPlan/View/Channel";
想象一下名稱重復(fù)十幾二十次的樣子。
因此,我們根據(jù)文件 的上下文來命名文件,根據(jù)組件的相對位置來命名組件是一種更好的方式。
頁面(Screen)屏幕,顧名思義,就是我們在應(yīng)用程序中展示出來的樣子。
如果要對一個用戶做增刪改查的操作,我們需要有用戶列表頁面,創(chuàng)建新用戶的頁面以及編輯已有用戶的頁面。
我們將screens 保存在src根目錄中的多帶帶文件夾中,因為它們將根據(jù)路由定義而不是模塊進(jìn)行分組:
src ├─ components └─ screens └─ User ├─ Form.jsx └─ List.jsx
考慮到項目使用react-router,我們將文件Root.jsx放在在screens目錄下,并在其中定義所有應(yīng)用程序路由。
Root.jsx 的代碼可能像下面這樣:
import React, { Component } from "react"; import { Router } from "react-router"; import { Redirect, Route, Switch } from "react-router-dom"; import ScreensUserForm from "./User/Form"; import ScreensUserList from "./User/List"; const ScreensRoot = () => (); export default ScreensRoot;
請注意,我們將所有頁面放在一個目錄中,這個目錄以路由名稱命名,user/ -> User/。嘗試為每個父級路由建立一個目錄,在這個目錄中組織子路由。 在這種情況下,我們創(chuàng)建了User目錄,并將List 頁面和Form頁面放入其中。這種方式使你看一眼 url 就能夠輕松定位當(dāng)前路由渲染的頁面。
單個頁面可用于渲染兩條不同的路線,如上所述,其中包含用于創(chuàng)建和編輯用戶的路線。
你可能會注意到所有組件都將Screen作為其名稱的前綴。 當(dāng)組件位于components 目錄之外時,我們應(yīng)該根據(jù)它到src文件夾的相對路徑來命名。 位于src/screens/User/List.jsx 的組件應(yīng)命名為ScreensUserList。
創(chuàng)建 Root.jsx 后,目錄的結(jié)構(gòu)如下:
src ├─ components └─ screens ├─ User │ ├─ Form.jsx │ └─ List.jsx └─ Root.jsx
如果你對一個頁面長什么樣子還有疑問,看看下面的示例,它就是用戶表單的頁面。
import React from "react"; import UserForm from "../../components/User/Form/Form"; const ScreensUserForm = ({ match: { params } }) => (); export default ScreensUserForm;{`${!params.id ? "Create" : "Update"}`} User
最后,我們的應(yīng)用程序結(jié)構(gòu)如下:
src ├─ components │ ├─ User │ │ ├─ Form │ │ │ ├─ Form.jsx │ │ │ └─ Form.css │ │ └─ List.jsx │ └─ UI │ └─ screens ├─ User │ ├─ Form.jsx │ └─ List.jsx └─ Root.jsx簡要回顧
展示組件和容器組件保存在src/components
按模塊/功能對組件進(jìn)行劃分
UI組件放大src/components/UI
保持頁面簡單,結(jié)構(gòu)和代碼最少
通過路由定義組織頁面。對于 /user/list 路由地址來說,我們會有一個頁面在 /src/screens/User/List.jsx。
組件根據(jù)其與組件或src的相對路徑進(jìn)行相應(yīng)命名。 鑒于此,位于src/components/User/List.jsx的組件將被命名為UserList。 位于src/screens/User/List的組件將命名為ScreensUserList
組件和目錄同名時,不要在使用組件的時候重復(fù)這個名字??紤]這樣一個場景,處于 src/components/User/List/List.jsx 位置的組件會被命名為 UserList 而不是 UserListList。
你的點贊是我持續(xù)分享好東西的動力,歡迎點贊!
歡迎加入前端大家庭,里面會經(jīng)常分享一些技術(shù)資源。文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/109936.html
摘要:解決思路服務(wù)器端渲染服務(wù)器端和前端公用同一個應(yīng)用,然后通過構(gòu)建工具及配置,確定哪些組件需要再服務(wù)器端渲染,那些組件需要再客戶端渲染。服務(wù)器端渲染,由框架與構(gòu)建工具配合,并依據(jù)一定的項目結(jié)構(gòu)和編碼方式,共同運行。 分離 為什么需要 前后端分離、web服務(wù)器與static服務(wù)器分離: 前端與后端耦合 (需求) 自動化、工程化的構(gòu)建前端的代碼 (基礎(chǔ)條件) 模塊化、組件化,項目共享代碼 (...
摘要:組件劃分這種的話組件劃分的比較清晰。將組件強勢得分為類,這種結(jié)構(gòu)上雖然非常清晰,但是在項目開發(fā)的過程中你不得不頻繁地將組件在跟之間移來移去,降低了開發(fā)體驗。 緣由 在開發(fā)項目的過程中,大家多多少少會對自己項目的目錄結(jié)構(gòu)產(chǎn)生疑惑,如何合理地劃分模塊以及如何合理的命名,這些如果在項目前期的時候沒有好好規(guī)范好的話,那么后面新進(jìn)來的人便會按照自己的邏輯又重新在劃分自己的目錄,這樣日復(fù)一日項目體...
書籍完整目錄 4.1 react 代碼規(guī)范 showImg(https://segmentfault.com/img/bVyE9m); 關(guān)于 基礎(chǔ)規(guī)范 組件結(jié)構(gòu) 命名規(guī)范 jsx 書寫規(guī)范 eslint-plugin-react 關(guān)于 在代碼的設(shè)計上,每個團(tuán)隊可能都有一定的代碼規(guī)范和模式,好的代碼規(guī)范能夠提高代碼的可讀性便于協(xié)作溝通,好的模式能夠上層設(shè)計上避免不必要的 bug 出現(xiàn)。本節(jié)會參考...
摘要:發(fā)布是由團(tuán)隊開源的,操作接口庫,已成為事實上的瀏覽器操作標(biāo)準(zhǔn)。本周正式發(fā)布,為我們帶來了,,支持自定義頭部與腳部,支持增強,兼容原生協(xié)議等特性變化。新特性介紹日前發(fā)布了大版本更新,引入了一系列的新特性與提升,本文即是對這些變化進(jìn)行深入解讀。 showImg(https://segmentfault.com/img/remote/1460000012940044); 前端每周清單專注前端...
摘要:首次發(fā)表在個人博客總結(jié)一下個人在開發(fā)及同事代碼的過程中遇到的因為一些項目規(guī)范帶來的問題及認(rèn)為比較好的解決方法由于個人經(jīng)驗和認(rèn)知水平有限下面僅代表我的個人觀念歡迎各位大佬多給我提建議以本人最近寫的一個項目技術(shù)棧為為例的使用因為一個項目往 showImg(http://upload-images.jianshu.io/upload_images/3297464-ccdb78e5d7d158...
閱讀 1204·2021-09-22 15:24
閱讀 2300·2019-08-30 15:44
閱讀 2630·2019-08-30 10:55
閱讀 3371·2019-08-29 13:25
閱讀 1655·2019-08-29 13:09
閱讀 1408·2019-08-26 14:05
閱讀 1402·2019-08-26 13:58
閱讀 1994·2019-08-26 11:57