跳到主要内容

前端

本頁包含有關如何編寫可讀代碼(也稱為編碼風格指南)的提示。

“並不”意味著您需要嚴格遵循指南,效率與維護一樣重要。

  • 對於舊項目,只要不造成任何副作用,歡迎進行重構工作。

  • 歡迎提出任何意見/問題。

命名慣例

  1. 不要過度使用簡短的語法和/或縮寫

    使代碼易於閱讀和理解。使其具有傳達性,

    即使這意味著它會更冗長,花費更多時間和精力來編寫。

    這也適用於文件和目錄的命名!

    const hasDevelopers = project.id && project.developers.length !== 0;
    if (hasDevelopers) {
    //doSomething()
    }
  2. 在推送到 Gitlab 之前刪除或註釋掉控制台

    console 經常用於在開發/調試時顯示數據,

    完成工作後,應該刪除/註釋掉,因為其他開發人員將不知道是否需要這樣做,

    除非確定它確實有幫助,如錯誤處理程序,

    隨著時間的推移,它可能會導致很大的污染。

  3. 使用具有聲明性名稱的函數

    是否匿名不重要,只要它描述了它的目的,

    並使用 getsetcreatedelete 等前綴。

  4. 儘量遵循 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);
    • 布爾值 - 使用 駝峰式命名法,並帶有以下前綴之一:isarehas
    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

通用

  1. 使用函數組件而不是類組件

    const MachineList = ({ machines }) => {
    //...
    return (
    <Fragment>
    {machines.map((machine) => (
    <MachineItem machine={machine} />
    ))}
    </Fragment>
    );
    };
  2. 避免直接將 setState 作為 prop 傳遞

    //不好 ❌
    <SomeComponent onChange={setState} />
    //好 ⭕️
    <SomeComponent
    onChange={(newValue) => {
    setState(newValue);
    }}
    />
  3. 整理代碼中的導入模塊

    這樣我們可以直觀

地看到哪些模塊是我們項目中的模塊,哪些是從 node_modules/ 或 Node.js 內置模塊中導入的。

import { useState } from "react";
import moment from "moment";

import { SomeButton } from "src/components/atoms";
import { SomeForm } from "src/components/organisms";

類型

  1. 定義接口作為 props,而不是類型

    //不好 ❌

    type MachineTableProps = {};
    //好 ⭕️

    interface MachineTableProps {}
  2. 避免使用 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>;
    };

項目結構

  1. 使用 [Atomic Design] 進行組織。

    每個項目可能具有不同的包/框架,但基本上它們遵循 [Atomic Design](特別是新項目)

    為了進行更好的測試,它們按用途分為兩個子類別:

    • 使用 API 數據的組件templatespages
    • 使用模擬數據的組件atomsmoleculesorganisms
  2. 通過常見後綴為組件命名以描述其功能(聲明性名稱)


後綴示例:
**_Form
_**Item
**_List
_**Card
**_Board
_**Page
\*\*\*Screen

const MachineList = ({ machines }) => {
//...
return (
<>
{machines.map((machine) => (
<MachineItem machine={machine} />
))}
</>
);
};
  1. 按功能進行子類別劃分

    基於 [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