javascript專案開發規範例項

funnycoderstar發表於2017-12-05

title

首次發表在個人部落格

總結一下個人在開發及review同事程式碼的過程中遇到的因為一些專案規範帶來的問題及認為比較好的解決方法; 由於個人經驗和認知水平有限,下面僅代表我的個人觀念,歡迎各位大佬多給我提建議;

以本人最近寫的一個專案(技術棧為Meteor + React + MongoDB)為例

readme的使用

因為一個專案往往需要很多人一起協助開發,還有可能會不斷有新手接手專案,所以readme裡面一定要僅可能多的資訊

  • 專案啟動命令
  • 程式碼規範
  • Commit Message 編寫規範
  • 命名: class命名,變數命名,函式命名,元件命名等
  • 元件
  • 目錄結構
  • 常遇到的問題及解決方案

也可以加一些專案中遇到的設計到的文件連結

程式碼規範

eslint

使用eslint來約束團隊統一的程式碼規則

eslint規則在.eslintrc.js中定義,覺得不合理的可以跟團隊成員商量禁掉某條規則,或者有好的建議的也可以新增; 主要注意一下幾條:

  • 程式碼縮排用4空格
  • 語句必須預設後加分號
  • 使用單引號
  • 提交程式碼前將console.log語句刪掉或註釋掉(不然影響其他開發人員除錯)
  • 禁止使用var,使用es6的let,const宣告變數

還有一些情況是不需要檢測的,例如第3方的庫, 框架、元件、ui庫等等,可以將這些檔案放在.eslintignore檔案中,可以忽略eslint的檢測

在檔案頂部加上下面這行,可以禁掉整個檔案的eslint規則

/* eslint-disable */
複製程式碼

pre-commit 的使用

使用方法 1.在命令列安裝

npm  i --save-dev pre-commit
複製程式碼

2.在package.json中配置

{
    "scripts": {
        "eslint": "eslint ./ --ext js,vue --ignore-pattern .eslintignore --cache --fix",
        "lint-message": "echo '開始 eslint 檢查, 存在 error 則會拒絕提交'"
    },
    "pre-commit": [
        "lint-message",
        "eslint" // 進行eslint檢查並自動修復一些簡單的格式錯誤
    ],
}
複製程式碼

程式碼提交之前會強制code-review,不符合規範的不允許提交程式碼

如果專案實在沒時間去改的話,可以git commit -m 'XXX' --no-verify 或 git commit -n 'xxx'強制提交

小技巧-vscode可以配置儲存自動修復eslint錯誤

vscode安裝eslint外掛,在配置中配置如下

{
     "eslint.autoFixOnSave": true,
     "eslint.enable": true,
     "eslint.options": {
        "extensions": [".js", ".vue", ".jsx"]
     },
     "eslint.validate": [
          {

              "language": "vue",
              "autoFix": true
          },
          {
              "language": "javascript",
              "autoFix": true
          },
          {
              "language": "javascriptreact",
              "autoFix": true
          }
      ],
}
複製程式碼

Commit Message 編寫規範

編寫Commit Message需要遵循一定的正規化,內容應該清晰明瞭,指明本次提交的目的,便於日後追蹤問題。

feat: 新功能
fix: 修補bug
docs: 文件
style: 格式(不影響程式碼執行的變動)
refactor: 重構
test: 新增測試
chore: 構建過程或輔助工具的變動

複製程式碼

命名

命名的語義化真的特別特別重要,哪怕不知道要命名的這個詞的英文是什麼,也要去查一下;千萬不要以a,b,c等沒有任何語義的詞去命名;之前我也總是注意不到這一點,但是最近在看同事的程式碼還有重構自己之前寫的部分程式碼,命名壓根看不明白這個變數的意思,總之,看這樣的程式碼怎一個痛苦了得

常見class命名關鍵詞: 佈局類:header, footer, container, main, content, aside, page, section 包裹類:wrap, inner 區塊類:region, block, box 結構類:hd, bd, ft, top, bottom, left, right, middle, col, row, grid, span 列表類:list, item, field 主次類:primary, secondary, sub, minor 大小類:s, m, l, xl, large, small 狀態類:active, current, checked, hover, fail, success, warn, error, on, off 導航類:nav, prev, next, breadcrumb, forward, back, indicator, paging, first, last 互動類:tips, alert, modal, pop, panel, tabs, accordion, slide, scroll, overlay, 星級類:rate, star 分割類:group, seperate, divider 等分類:full, half, third, quarter 表格類:table, tr, td, cell, row 圖片類:img, thumbnail, original, album, gallery 語言類:cn, en 論壇類:forum, bbs, topic, post 方向類:up, down, left, right 其他語義類:btn, close, ok, cancel, switch; link, title, info, intro, more, icon; form, label, search, contact, phone, date, email, user; view, loading...

變數命名: 名字要能準確的描述出該變數所代表的事物 比如表示userid就叫userId,而不要只叫user

函式命名建議:可使用常見動詞約定

 動詞       含義      
 get       獲取某個值            
 set       設定某個值             
 is        判斷是否為某個值    
 has       判斷是否有某個值  
複製程式碼

以下規則是此專案中使用的,主要看團隊程式碼習慣:

  1. 元件名和元件所在檔名使用大駝峰式
  2. css類名使用小寫單詞並用橫線(-)分割
  3. dom節點以$開頭

元件

  1. 每個元件佔一個檔案
  2. 元件不包含狀態則應寫為 stateless 元件
  3. 非 stateless 元件使用 pure-render-decorator 優化

目錄結構

├── client  
│   ├── main.html                       客戶端頁面模板
│   └── main.js                         客戶端入口  
├── imports  
│   ├── client  
│   │   ├── App.jsx                     頂層元件  
│   │   ├── components                  公共元件  
│   │   ├── routers                     前端路由  
│   │   ├── styles                      樣式  
│   │   └── views                       檢視  
│   │       ├── header                  公共頭  
│   │       ├── login                   登入註冊  
│   ├── schema                          模型  
│   └── util                            工具函式  
├── packages                            自定義 meteor 包  
├── public                              客戶端資源  
└── server   
    ├── main.js                         服務端入口  
    └── user                            使用者介面  
複製程式碼

issues的使用

專案中總會遇到很多奇奇怪怪的問題,當時印象深刻,過了一段時間,就忘了具體的問題及解決辦法,雖然每次可以通過查commit為fix的記錄,但是這樣查詢起來很麻煩,我們專案是用gitlab來託管,可以合理的理由issues,每次遇到很棘手的問題的時候,可以提一個issues,等後期把這個問題解決了再把這個issues給關閉,並寫上問題原因及解決辦法分析

下面補充的是專案中針對Meteor後端開發的一些規範

資料庫

Collection 定義

所有 Collection 定義放在 imports/schema 目錄, 每個 Collection 務必定義 Schema 來約束欄位

Schema 定義

Schema 定義使用 SimpleSchema, 資料插入資料庫前必須通過 schema 校驗, 呼叫校驗語句為 表名.schema.validate(要插入的資料);

過濾 Collection 欄位

預設情況下, 資料查詢語句會返回所有欄位, 比如 Memete.users.find({}) 會將使用者的密碼和 token 一併返回, 這樣是不安全不正確的, find / findOne 的第二個引數是查詢選項, fields 欄位可以控制返回欄位, 例如:

Meteor.users.find(
    { },
    {
        fields: {
            username: 1,
            profile: 1,
        },
    },
);
複製程式碼

該查詢會返回 _id, username, profile 欄位, 其中 _id 是預設返回的

自己定義populate方法(取出關聯資料)

在做邀請新的好友入群的時候,新增新的好友,利用reywood:publish-composite並不會自動更新資料,所以以後直接自己在客戶端定義方法 這樣做的好處是解決了取關聯資料不會自動更新的bug,但是有點麻煩的是每次需要關聯資料的時候必須在客戶端呼叫一次方法,正在考慮有沒有更好的解決方法

import { Meteor } from 'meteor/meteor';

const PopulateUtil = {
    group(group) {
        if (group) {
            group.members = Meteor.users.find({ _id: { $in: group.members } }).fetch();
            group.admin = Meteor.users.findOne({ _id: group.admin });
        }
    },
    groups(groups) {
        groups.forEach(group => PopulateUtil.group(group));
    },
};

export default PopulateUtil;
複製程式碼

因為這次專案需要自己設計資料庫,還有自己定義後端方法,之前沒有任何經驗,做到現在也總結出一點心得:

  • 資料庫設計一定要根據具體的業務邏輯(開始設計之前一定要和產品溝通清楚產品邏輯)
  • 能在後端取到的資料,在介面定義的時候不要讓前端去傳

最後感覺後端的邏輯真的很複雜,需要各種判斷,各種情況都得想到

推薦看一下這本程式碼大全(第二版),等看完這本書再好好的完善一下這篇文章

參考

About

github blog

相關文章