前端進階(3) - 怎樣提高代碼質量

怎樣提高代碼質量

儘管寫了多年的代碼,可是始終有一件事不敢肯定,就是本身的代碼究竟寫得好很差?這個問題很難有確切的答案,由於這個跟風格、規範有很大關係,而風格、規範很難說好仍是很差。javascript

但我以爲好的代碼,必定是能讓別人閱讀起來有一種爽心悅目的感受。css

1. 開發規範

不論是團隊協做仍是我的獨立開發,遵循必定的開發規範都是頗有必要的。就團隊協做來講,可能每一個人的風格迥然不一樣,若是沒有規範的約束的話,團隊之間的協做會大打折扣的。而就我的獨立開發來講,很難說一年後的你回頭看今天本身寫的代碼是滿意的。html

js 開發規範

通常前端開發的主要工做都要 js 部分,因此通常前端開發規範都是對 js 而言的。前端

承認度比較高的有:java

css 開發規範

承認度比較高的有:node

2. 使用工具檢查、自動矯正與優化

儘管有規範可循,但其實開發的時候並不知道本身的代碼是不是符合規範的,因此就須要工具來檢查與矯正代碼。react

2.1 檢查與自動矯正

承認度比較高的有:webpack

  1. eslint:檢查 js 語法(包括 jsx 語法),而後最大程度的矯正不符合規範的代碼;
  2. stylelint:檢查 css 語法(包括 less, scss 語法),而後最大程度的矯正不符合規範的代碼。

安裝

目錄文件git

|-- root/                    // 項目根目錄
    |-- package.json
    |-- .eslintrc            // eslint 配置文件
    |-- .eslintignore        // eslint 忽略配置,相似 .gitignore
    |-- .stylelintrc         // stylelint 配置文件
    |-- .stylelintignore     // stylelint 忽略配置,相似 .gitignore

package.jsones6

"scripts": {
  "eslint": "eslint .",                             // 僅檢查
  "eslint:fix": "eslint . --fix",                   // 檢查以後自動矯正
  
  "stylelint": "stylelint \"./**/*.{css,less,sass,scss}\"",             // 僅檢查
  "stylelint:fix": "stylelint \"./**/*.{css,less,sass,scss}\" --fix"    // 檢查以後自動矯正
},
"devDependencies": {
  "eslint": "^4.19.1",                              // eslint 主文件
  "babel-eslint": "^8.2.5",                         // babel 轉碼器 for eslint
  "eslint-config-airbnb": "^17.0.0",                // airbnb eslint 規則
  "eslint-config-prettier": "^2.9.0",               // prettier eslint 規則
  "eslint-plugin-babel": "^5.1.0",                  // eslint 的 babel 轉碼插件
  "eslint-plugin-import": "^2.13.0",                // eslint 檢查模塊輸入輸出是否正確的插件
  "eslint-plugin-jsx-a11y": "^6.1.0",               // eslint jsx 語法檢查的一個插件
  "eslint-plugin-prettier": "^2.6.2",               // prettier eslint 插件
  "eslint-plugin-react": "^7.10.0",                 // eslint react 語法檢查插件
  
  "stylelint": "^9.3.0",                            // stylelint 主文件
  "stylelint-config-prettier": "^3.3.0",            // prettier stylelint 規則
  "stylelint-config-standard": "^18.2.0"            // standard stylelint 規則
},

.eslintrc

{
  "parser": "babel-eslint",
  "extends": ["airbnb", "prettier"],
  "env": {
    "browser": true,
    "node": true,
    "es6": true,
    "mocha": true,
    "jest": true,
    "jasmine": true
  },
  "rules": {
    ... // 更多本身定義的規則
  }
}

.stylelintrc

{
  "extends": ["stylelint-config-standard", "stylelint-config-prettier"],
  "rules": {
    ... // 更多本身定義的規則
  }
}

運行命令

npm run eslint           // 檢查項目中的 js(jsx) 語法
npm run eslint:fix       // 檢查項目中的 js(jsx) 語法,並最大程度的矯正

npm run stylelint        // 檢查項目中的 css(less,scss) 語法
npm run stylelint:fix    // 檢查項目中的 css(less,scss) 語法,並最大程度的矯正

2.2 代碼優化

eslintstylelint 在對代碼作檢查和自動矯正時,只保證代碼的語法是符合必定的規範,並不對代碼的格式作任何優化,因此,自動矯正後的代碼可能格式會不太好,閱讀性不過高。

因此,通常會在對代碼檢查與自動矯正以後作代碼格式優化。

使用比較多的:prettier.

安裝

目錄文件

|-- root/                    // 項目根目錄
    |-- package.json
    |-- .prettierrc          // prettier 配置文件
    |-- .prettierignore      // prettier 忽略配置,相似 .gitignore

package.json

"scripts": {
  // 對 js,jsx,css,less,md,json 文件進行優化
  "prettier": "prettier --write \"./**/*.{js,jsx,css,less,md,json}\""
},
"devDependencies": {
  "prettier": "^1.13.7"
},

.prettierrc

{
  "singleQuote": true,
  "trailingComma": "es5",
  "printWidth": 120,
  "overrides": [
    {
      "files": ".prettierrc",
      "options": { "parser": "json" }
    }
  ]
}

運行命令

npm run prettier

2.3 強制對代碼進行檢查、自動矯正與優化

儘管定好了規範與工具命令,但開發人員徹底能夠跳過這些步驟,這尤爲是在團隊開發中很難強制其餘組員會去作代碼檢查、自動矯正與優化。

因此,使用工具強制開發人員對代碼進行檢查、自動矯正與優化,就顯得頗有必要了。

使用比較多的:

  • husky:對 git 進行 hook,能夠在 git 操做以前作一些操做;
  • lint-staged:對當前 git 提交的代碼進行一些操做。

package.json

"scripts": {
  "precommit": "npm run lint-staged",     // 在 git 提交以前運行 lint-staged 命令
  "lint-staged": "lint-staged",           // 對 git 將要提交的代碼作操做
},
"devDependencies": {
  "husky": "^0.14.3",
  "lint-staged": "^7.2.0",
},
"lint-staged": {
  "**/*.{js,jsx}": [
    "eslint --fix",                      // 對 js,jsx 文件進行 eslint 檢查、自動矯正 
    "prettier --write",                  // 而後 使用 prettier 進行代碼格式優化
    "git add"                            // 最後從新添加
  ],
  "**/*.{css,less}": [
    "stylelint --fix",                   // 對 css,less 文件進行 stylelint 檢查、自動矯正
    "prettier --write",                  // 而後 使用 prettier 進行代碼格式優化
    "git add"                            // 最後從新添加
  ],
  "**/*.{md,json}": [
    "prettier --write",                  // 使用 prettier 進行代碼格式優化
    "git add"                            // 最後從新添加
  ]
},

這樣,在每次 git commit 以前,都會對將要提交的文件進行檢查、自動矯正與優化,若是其中有一項發生錯誤,本次提交都會失敗。而後開發人員調整代碼以後再進行提交,只有每項任務都是沒問題的,才能提交成功。

這樣,即可使每一個開發人員都是按照必定的規範與風格寫代碼的。

3. 編輯器配置:.editorconfig

有了規範,也加上了工具作自動化代碼檢查、矯正與優化,但還有一點須要說起一下,就是在團隊協做中,每一個開發人員可能使用的編輯器不同,編輯器的配置也不同,這就致使工具在作格式優化的時候,不一樣的開發人員中輸出的代碼不同。

這就須要配置文件 .editorconfig 去統一每一個開發人員的編輯器配置。

目錄文件

|-- root/                    // 項目根目錄
    |-- .editorconfig        // 編輯器配置文件

.editorconfig

# http://editorconfig.org
root = true

[*]
indent_style = space                    # 輸入的 tab 都用空格代替
indent_size = 2                         # 一個 tab 用 2 個空格代替
end_of_line = lf                        # 換行符使用 unix 的換行符 \n
charset = utf-8                         # 字符編碼 utf-8
trim_trailing_whitespace = true         # 去掉每行末尾的空格
insert_final_newline = true             # 每一個文件末尾都加一個空行

[*.md]
trim_trailing_whitespace = false        # .md 文件不去掉每行末尾的空格

更多的編輯器配置規則,能夠查看 http://editorconfig.org.

4. 業務邏輯優化

上面提到的這些只是風格、規範、語法上的優化,但對編碼質量的評估更多的是在業務邏輯具體實現這一塊。

通常來講,業務邏輯實現的優化離不開下面幾個方向:

  1. 模塊化:

    • js 的模塊化已經很成熟了,目前使用最多的是 commonjs 模塊化規範和 es6 模塊;
    • css 的模塊化也一直在探索中,以前也專門寫了一篇 CSS 模塊化,能夠參考下;
    • html 沒有模塊化,可是能夠將一個很長的 html 文件進行分塊,參考 html-loader
  2. 組件化:當項目變大、變多,不少公共的代碼須要複用或者跨項目使用的時候,組件化就變得很必要了,以前也專門寫了一篇 組件化,能夠參考下;
  3. 邏輯解耦:把一個複雜的邏輯,分割成多個子邏輯,而後將子邏輯串起來,或者把多個交叉邏輯的公共部分拆出來,而後再挨個串起來;
  4. 功能分塊:細化一個一個的功能爲單獨的模塊。

5. 邏輯解耦

邏輯解耦就是把一個複雜的邏輯,分割成多個子邏輯,或者把多個交叉邏輯的公共部分拆成單個邏輯。這樣作的目的是下降應用的複雜度,更據閱讀性。

好比,3 個串行的 ajax 請求,能夠分割成多個子邏輯:

$.getJSON(url1, data1, res1 => {
  // do something with res1
  
  $.getJSON(url2, data2, res2 => {
    // do something with res2
    
    $.getJSON(url3, data3, res3 => {
      // do something with res3
    });
  });
});

邏輯解耦以後:

const request1 = () => {
  $.getJSON(url1, data1, res1 => {
    // do something with res1
    
    request2();
  }
};
const request2 = () => {
  $.getJSON(url2, data2, res2 => {
    // do something with res2
    
    request3();
  }
};
const request3 = () => {
  $.getJSON(url3, data3, res3 => {
    // do something with res3
  }
};

request1();

再好比,在不一樣文件中須要依賴同一個 ajax 請求,能夠把交叉邏輯的部分拆成單個邏輯:

# file1.js

$.getJSON(url, data, res => {
  // do something with res
}

# file2.js

$.getJSON(url, data, res => {
  // do something with res
}

邏輯解耦以後:

# request.js

module.exports = cb => {
  $.getJSON(url, data, res => {
    cb(res);
  }
};

# file1.js

const request = require('./request');
request(res => {
  // do something with res
});

# file2.js

const request = require('./request');
request(res => {
  // do something with res
});

6. 功能分塊

細化功能爲單獨的模塊也是提高代碼質量的一個方式。

好比,將一個文件拆成多個文件(顆粒化):

# util.js

module.exports = {
  func1: args => { ... },
  func2: args => { ... },
  func3: args => { ... },
};

將功能分塊以後:

# util/func1.js

module.exports = args => { ... };

# util/func2.js

module.exports = args => { ... };

# util/func3.js

module.exports = args => { ... };

再好比,將一個大功能塊分割成多個小功能塊:

$.getJSON(url, data, res => {
  // 渲染頁面
  ...
  
  // 初始化組件
  ...
  
  // 裝載數據
  ...
  
  // 綁定模型
  ...
  
  // ...
  ...
}

通常這種狀況下,一個功能代碼塊就可能會很長,200 行都有可能,這個時候就須要將其分割成多個小代碼塊:

const renderPages = res => { ... };
const initComponents = res => { ... };
const fillData = res => { ... };
const bindModels = res => { ... };
...

$.getJSON(url, data, res => {
  // 渲染頁面
  renderPages();
  
  // 初始化組件
  initComponents();
  
  // 裝載數據
  fillData()
  
  // 綁定模型
  bindModels();
  
  // ...
  ...
}

7. 多閱讀

最後,也是最重要的,就是多閱讀別人優秀的代碼,閱讀永遠是獲取知識最重要的途徑,沒有之一。

8. 後續

更多博客,查看 https://github.com/senntyou/blogs

做者:深予之 (@senntyou)

版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證

相關文章
相關標籤/搜索