前端
本頁包含有關如何編寫可讀代碼(也稱為編碼風格指南)的提示。
這“並不”意味著您需要嚴格遵循指南,效率與維護一樣重要。
對於舊項目,只要不造成任何副作用,歡迎進行重構工作。
歡迎提出任何意見/問題。
命名慣例
不要過度使用簡短的語法和/或縮寫。
使代碼易於閱讀和理解。使其具有傳達性,
即使這意味著它會更冗長,花費更多時間和精力來編寫。
這也適用於文件和目錄的命名!
const hasDevelopers = project.id && project.developers.length !== 0;
if (hasDevelopers) {
//doSomething()
}在推送到 Gitlab 之前刪除或註釋掉控制台
console經常用於在開發/調試時顯示數據,完成工作後,應該刪除/註釋掉,因為其他開發人員將不知道是否需要這樣做,
除非確定它確實有幫助,如錯誤處理程序,
隨著時間的推移,它可能會導致很大的污染。
使用具有聲明性名稱的函數。
是否匿名不重要,只要它描述了它的目的,
並使用
get、set、create、delete等前綴。儘量遵循 JavaScript 命名慣例最佳實踐。
感謝 [命名慣例最佳實踐文章]。
- 常量 -
大寫字母
const SECONDS = 60;
const MINUTES = 60;
const HOURS = 24;
const DAY = SECONDS * MINUTES * HOURS;它們應該始終保持在全局範圍內,以避免在函數計算時過度負荷或浪費內存轉儲。這種方式在閱讀代碼時也容易導航。
- 變量 -
駝峰式命名法
const firstName = "Matt";- 瀏覽器使用的變量,例如輸入字段 -
短橫線命名法
<input name="variable-name-in-kebab-case" />- 存儲在 API 中的變量,以 JSON 形式 -
蛇式命名法
{
"machine_id": "randomId12345",
"machine_name": "Awesome machine name"
}- CSS 樣式類名 -
蛇式命名法
.component_name {
display: flex;
}原因: 語法一致性且使用時更容易,而無需引用它,
例如:
const classNames = clsx(CSS.component_name, CSS.error);而不是:
const classNames = clsx(CSS["component-name"], CSS.error);- 布爾值 - 使用
駝峰式命名法,並帶有以下前綴之一:is、are、has
const isVisible = true;
const areEqual = false;
const hasEncryption = true;- 函數 -
駝峰式命名法
function getName(firstName, lastName) {
return `${firstName} ${lastName}`;
}- 類 -
大駝峰式命名法
class SoftwareDeveloper {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}- 方法 -
駝峰式命名法
class SoftwareDeveloper {
getName() {
return ( ... );
};
}- 組件(任何框架中) -
大駝峰式命名法
const UserProfile = (props) {
return ( ... );
}- 接口/類型(TypeScript) -
大駝峰式命名法
type MachinData {}
interface MachineTableProps {}- 常量 -
React
通用
使用函數組件而不是類組件
const MachineList = ({ machines }) => {
//...
return (
<Fragment>
{machines.map((machine) => (
<MachineItem machine={machine} />
))}
</Fragment>
);
};避免直接將 setState 作為 prop 傳遞
//不好 ❌
<SomeComponent onChange={setState} />//好 ⭕️
<SomeComponent
onChange={(newValue) => {
setState(newValue);
}}
/>整理代碼中的導入模塊。
這樣我們可以直觀
地看到哪些模塊是我們項目中的模塊,哪些是從 node_modules/ 或 Node.js 內置模塊中導入的。
import { useState } from "react";
import moment from "moment";
import { SomeButton } from "src/components/atoms";
import { SomeForm } from "src/components/organisms";
類型
定義接口作為 props,而不是類型
//不好 ❌
type MachineTableProps = {};//好 ⭕️
interface MachineTableProps {}避免使用 FC/FunctionalComponent,直接使用 SomeComponentProps
export interface SomeComponentProps {
name: string;
}//不好 ❌
export const SomeComponent: FC<SomeComponentProps> = ({ name = "" }) => {
return <div>{ name }<div>;
};//好 ⭕️
export const SomeComponent = ({ name = "" }: SomeComponentProps) => {
return <div>{ name }<div>;
};
項目結構
使用 [Atomic Design] 進行組織。
每個項目可能具有不同的包/框架,但基本上它們遵循 [Atomic Design](特別是新項目)
為了進行更好的測試,它們按用途分為兩個子類別:
- 使用 API 數據的組件:
templates和pages - 使用模擬數據的組件:
atoms、molecules和organisms
- 使用 API 數據的組件:
通過常見後綴為組件命名以描述其功能(聲明性名稱)
後綴示例:
**_Form
_**Item
**_List
_**Card
**_Board
_**Page
\*\*\*Screen
const MachineList = ({ machines }) => {
//...
return (
<>
{machines.map((machine) => (
<MachineItem machine={machine} />
))}
</>
);
};
按功能進行子類別劃分
基於 [Atomic Design],可重用的組件不應僅設計給單個頁面/組件使用,
即使對其他頁面來說實際上是無用的。也就是說,不建議將組件放入按路由/頁面命名的子類別中。
應該是
organisms
|_ forms
| |_UserLoginForm.js
| |_MachineForm.js
|
|_index.js而不是
organisms
|_ userLogin
| |_Form
.js | |_ machineForm |_Form.js
1. **文件名按駝峰式命名法命名**
使用 `大駝峰式命名法` 命名文件,方便區分目錄和文件,
並且在某些版本控制系統(如 Windows)上對文件名區分大小寫。
- **組件文件** - `SomeComponent.js`
- **樣式文件** - `someComponentStyles.css`
- **測試文件** - `SomeComponent.test.js`
- **子組件文件** - `SomeComponentChild.js`
- **頂級組件** - `src/components/SomeComponent.js`
1. **在同一目錄中為組件創建單獨的文件夾**
- **將所有組件相關文件放在一個文件夾中**
- **以相關文件名命名文件夾**
/src/components/SomeComponent/ | SomeComponent.js | SomeComponent.styles.css |_ SomeComponent.test.js
1. **拆分大的組件**
如果一個組件變得非常龐大,難以理解和維護,
請考慮將其拆分為更小的子組件。
1. **組件內部文件按用途劃分**
如果一個組件包含多個文件,按用途劃分它們,
例如,將樣式文件和測試文件放在不同的文件夾中:
/src/components/SomeComponent/ | SomeComponent.js | styles/ | | SomeComponent.styles.css | tests/ |_ SomeComponent.test.js
[atomic design]: https://bradfrost.com/blog/post/atomic-web-design/
[storybook]: https://storybook.js.org/
[the article about the naming convention best practices]: https://javascript.plainenglish.io/javascript-naming-convention-best-practices-b2065694b7d