久久国产乱子伦精品免费观看_亚洲欧美日韩综合在线丁香_欧 美 成 人 网站在线观看_最新欧美电影免费在线_国产精品操干在线观看_最近中文字幕在线视频1_69天堂人成无码_国产影视一区二区三区_中文亚洲精油按摩色偷偷av_99自拍偷拍视频

您當前的位置:首頁 > 新聞中心 > 行業(yè)新聞
中小型前端團隊代碼規(guī)范工程化最佳實踐 - ESLint 2021年04月22日

中小型前端團隊代碼規(guī)范工程化最佳實踐 - ESLint


前言

 

There are a thousand Hamlets in a thousand people's eyes.

 

一千個程序員,就有一千種代碼風格。在前端開發(fā)中,有幾個至今還在爭論的代碼風格差異:
 

  • 單引號還是雙引號?

  • 代碼行結(jié)束是否需要分號?

  • 兩個空格還是四個空格?

  • ...

這幾個代碼風格差異在協(xié)同開發(fā)中經(jīng)常會被互相吐槽,甚至不能忍受。除此之外,由于 JavaScript 的靈活性,往往一段代碼能有多種寫法,這時候也會導致協(xié)同時差異。并且,有一些寫法可能會導致不易發(fā)現(xiàn)的 bug,或者這些寫法的性能不好,開發(fā)時也應該避免。為了解決這類靜態(tài)代碼問題,每個團隊都需要一個統(tǒng)一的 JavaScript 代碼規(guī)范,團隊成員都遵守這份代碼規(guī)范來編寫代碼。當然,靠人來保障代碼規(guī)范是不可靠的,需要有對應的工具來保障,ESLint 就是這個工具。有的讀者看到這里,可能會說:Prettier 也可以保證代碼風格一致。是的,Prettier 確實可以按照設置的規(guī)則對代碼進行統(tǒng)一格式化,后面的文章也會有對應的介紹。但是需要明確的一點是,Prettier 只會在格式上對代碼進行格式化,一些隱藏的代碼質(zhì)量問題 Prettier 是無法發(fā)現(xiàn)的,而 ESLint 可以。

關于 ESLint

關于 ESLint,它的 Slogan 是 Find and fix problems in your JavaScript code。如上文所說,它可以發(fā)現(xiàn)并修復你 JavaScript 代碼中的問題。來看一下官網(wǎng)上描述 ESLint 具備的三個特性:

  • Find Problems。ESLint 通過靜態(tài)代碼分析可以快速發(fā)現(xiàn)代碼中的問題。ESLint 可以運行在大多數(shù)文本編輯器中,并且也可以在工作流中接入 ESLint

  • Fix Automatically。ESLint 發(fā)現(xiàn)的很多問題都可以自動修復

  • Customize??梢远ㄖ?ESLint 檢查規(guī)則

基于以上描述,我們在前端工程化中可以這樣使用 ESLint:

  1. 基于業(yè)界現(xiàn)有的 ESLint 規(guī)范和團隊代碼習慣定制一套統(tǒng)一的 ESLint 代碼規(guī)則

  2. 將統(tǒng)一代碼規(guī)則封裝成 ESLint 規(guī)則包接入

  3. 將 ESLint 接入腳手架、編輯器以及研發(fā)工作流中

快速上手

先簡單介紹一下如何使用 ESLint,如果已經(jīng)有所了解的同學,可以直接跳過這一節(jié)。新建一個包含 package.json 的目錄(可以在空目錄下執(zhí)行 npm init -y),新建一個 index.js:// index.js
const name = 'axuebin'
安裝 eslint :npm install eslint --save-dev
然后執(zhí)行 ./node_modules/.bin/eslint --init 或者 npx eslint --init 生成一個 ESLint 配置文件 .eslintc.js:module.exports = {
  env: {
    es2021: true,
  },
  extends: 'eslint:recommended',
  parserOptions: {
    ecmaVersion: 12,
  },
  rules: {},
};
生成好配置文件之后,就可以執(zhí)行 ./node_modules/.bin/eslint index.js 或者 npx eslint index.js 命令對文件進行檢查。結(jié)果如下
 

index.js 中的代碼命中了 no-unused-vars 這個規(guī)則,默認情況下,這個規(guī)則是會報 error 的,也就是 ESLint 不允許代碼中出現(xiàn)未被使用的變量。這是一個好習慣,有利于代碼的維護。
 

簡單配置

我們來嘗試配置 ESLint 的檢查規(guī)則。以分號和引號舉例,現(xiàn)在你作為團隊代碼規(guī)范的指定人,希望團隊成員開發(fā)的代碼,都是單引號和帶分號的。
打開 .eslintrc.js 配置文件,在 rules 中添加相關配置項:module.exports = {
  env: {
    es2021: true,
  },
  extends: 'eslint:recommended',
  parserOptions: {
    ecmaVersion: 12,
  },
  rules: {
    semi: ['error''always'],
    quotes: ['error''single'],
  },
};
然后我們將 index.js 中的代碼改成:// index.js
const name = "axuebin"
執(zhí)行 eslint 命令之后:


可以看到檢查結(jié)果如下:
 

  • [no-unused-vars] 'name' is assigned a value but never used。定義了 name 變量卻未使用。

  • [quotes] Strings must use singlequote。字符串必須使用單引號。

  • [semi] Missing semicolon。缺失分號。

老老實實地按照規(guī)范修改代碼,使用單引號并將加上分號。當然,如果你們希望是雙引號和不帶分號,修改相應的配置即可。具體各個規(guī)則如何配置可以查看:https://eslint.org/docs/rules

自動修復

執(zhí)行 eslint xxx --fix 可以自動修復一些代碼中的問題,將無法自動修復的問題暴露出來。比如上文中提到的引號和分號的問題,就可以通過 --fix 自動修復,而 no-unused-vars 變量未使用的問題,ESLint 就無法自動修復。

使用配置包在 init 生成的配置文件中,我們看到包含這一行代碼:module.exports = {
  extends: "eslint:recommended"
}
這一行代碼的意思是,使用 ESLint 的推薦配置。 extends: 'xxx' 就是 繼承,當前的配置繼承于 xxx 的配置,在此基礎上進行擴展。
因此,我們也可以使用任意封裝好的配置,可以在 NPM 上或者 GItHub 上搜索 eslint-config 關鍵詞獲取,本文我們將這類封裝好的配置稱作 “配置集”。比較常見的配置包有以下幾個:

  • eslint-config-airbnb: Airbnb 公司提供的配置集

  • eslint-config-prettier: 使用這個配置集,會關閉一些可能與 Prettier 沖突的規(guī)則

  • eslint-config-react: create react app 使用的配置集

  • eslint-config-vue: vuejs 使用的配置集

  • ...

最佳實踐

簡單了解完 ESLint 之后,對于 ESLint 的更多使用細節(jié)以及原理,在本篇文章就不展開了,感興趣的朋友可以在官網(wǎng)詳細了解。本文重點還是在于如何在團隊工程化體系中落地 ESLint,這里提幾個最佳實踐。

抽象配置集

對于獨立開發(fā)者以及業(yè)務場景比較簡單的小型團隊而言,使用現(xiàn)成、完備的第三方配置集是非常高效的,可以較低成本低接入 ESLint 代碼檢查。但是,對于中大型團隊而言,在實際代碼規(guī)范落地的過程中我們會發(fā)現(xiàn),不可能存在一個能夠完全符合團隊風格的三方配置包,我們還是會在 extends 三方配置集的基礎上,再手動在 rules 配置里加一些自定義的規(guī)則。時間長了,有可能 A 應用和 B 應用里的 rules 就不一樣了,就很難達到統(tǒng)一的目的。這時候,就需要一個中心化的方式來管理配置包:根據(jù)團隊代碼風格整理(或者基于現(xiàn)有的三方配置集)發(fā)布一個配置集,團隊統(tǒng)一使用這個包,就可以做到中心化管理和更新。除此之外,從技術層面考慮,目前一個前端團隊的面對的場景可能比較復雜。比如:

  • 技術選型不一致:框架上 PC 使用 React,H5 使用 Vue;是否使用 TypeScript

  • 跨端場景多:Web 端和小程序端,還有 Node

  • ...

以上問題在真實開發(fā)中都是存在的,所以在代碼規(guī)范的工程化方案落地時,一個單一功能的配置集是不夠用的,這時候還需要考慮這個配置集如何抽象。為了解決以上問題,這里提供一種解決方案的思路:

具體拆解來看,就是有一個類似 eslint-config-standard 的基礎規(guī)則集(包括代碼風格、變量相關、ES6 語法等),在此基礎之上集成社區(qū)的一些插件(Vue/React)等,封裝成統(tǒng)一的一個 NPM Package 發(fā)布,消費時根據(jù)當前應用類型通過不同路徑來 extends 對應的配置集。
這里有一個 Demo,感興趣的朋友可以看一下:eslint-config-axuebin

開發(fā)插件

ESLint 提供了豐富的配置供開發(fā)者選擇,但是在復雜的業(yè)務場景和特定的技術棧下,這些通用規(guī)則是不夠用的。ESLint 通過插件的形式賦予了擴展性,開發(fā)者可以自定義任意的檢查規(guī)則,比如 eslint-plugin-vue / eslint-plugin-react 就是 Vue / React 框架中使用的擴展插件,官網(wǎng)也提供了相關文檔引導開發(fā)者開發(fā)一個插件。一般來說,我們也不需要開發(fā)插件,但我們至少需要了解有這么個東西。在做一些團隊代碼質(zhì)量檢查的時候,我們可能會有一些特殊的業(yè)務邏輯,這時候 ESLint 插件是可以幫助我們做一些事情。這里就不展開了,主要就是一些 AST 的用法,照著官方文檔就可以上手,或者可以參考現(xiàn)有的一些插件寫法。

腳手架 / CLI 工具

當有了團隊的統(tǒng)一 ESLint 配置集和插件之后,我們會將它們集成到腳手架中,方便新項目集成和開箱即用。但是對于一些老項目,如果需要手動改造還是會有一些麻煩的,這時候就可以借助于 CLI 來完成一鍵升級。本文結(jié)合上文的 Demo eslint-config-axuebin,設計一個簡單的 CLI Demo。由于當前配置也比較簡單,所以 CLI 只需要做幾件簡單的事情即可:

  • 詢問用戶當前項目的類型(是 JavaScript 還是 TypeScript、是 React 還是 Vue)

  • 根據(jù)項目類型寫 .eslintrc.js 文件

  • 根據(jù)項目類型安裝所需依賴(比如 vue 需要 eslint-plugin-vue)

  • 在 package.json 的 scripts 中寫入 "lint": "eslint src test --fix"  

核心代碼如下:const path = require('path');
const fs = require('fs');
const chalk = require('chalk');
const spawn = require('cross-spawn');

const { askForLanguage, askForFrame } = require('./ask');
const { eslintrcConfig, needDeps } = require('./config');

module.exports = async () => {
  const language = await askForLanguage();
  const frame = await askForFrame();

  let type = language;
  if (frame) {
    type += `/${frame}`;
  }

  fs.writeFileSync(
    path.join(process.cwd(), '.eslintrc.js'),
    `// Documentation\n// https://github.com/axuebin/eslint-config-axuebin\nmodule.exports = ${JSON.stringify(
      eslintrcConfig(type),
      null,
      2
    )}`
  );

  const deps = needDeps.javascript;
  if (language === 'typescript') {
    deps.concat(needDeps.typescript);
  }
  if (frame) {
    deps.concat(needDeps[frame]);
  }

  spawn.sync('npm', ['install', ...deps, '--save'], { stdio: 'inherit' });
};
可運行的 CLI Demo 代碼見:axb-lint,在項目目錄下執(zhí)行:axblint eslint 即可,如圖:
 

自動化
配置了 ESLint 之后,我們需要讓開發(fā)者感知到 ESLint 的約束。開發(fā)者可以自己運行 eslint 命令來跑代碼檢查,這不夠高效,所以我們需要一些自動化手段來做這個事情。當然 在開發(fā)時,編輯器也有提供相應的功能可以根據(jù)當前工作區(qū)下的 ESLint 配置文件來檢查當前正在編輯的文件,這個不是我們關心的重點。一般我們會在有以下幾種方式做 ESLint 檢查:

  • 開發(fā)時:依賴編輯器的能力

  • 手動運行:在終端中手動執(zhí)行 eslint 命令

  • pre-commit:在提交 git 前自動執(zhí)行 eslint 命令

  • ci:依賴 git 的持續(xù)集成,可以將檢查結(jié)果輸出文件上傳到服務器

這里提一下 pre-commit 的方案,在每一次本地開發(fā)完成提交代碼前就做 ESLint 檢查,保證云端的代碼是統(tǒng)一規(guī)范的。這種方式非常簡單,只需要在項目中依賴 husky 和 lint-staged 即可完成。安裝好依賴之后,在 package.json 文件加入以下配置即可:{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}""eslint --cache --fix"
  },
  "husky": {
    "hooks": {
      "pre-commit""lint-staged"
    }
  }
}
效果如圖所示:
 

如果代碼跑 ESLint 檢查拋了 Error 錯誤,則會中斷 commit 流程:
 

這樣就可以確保提交到 GitHub 倉庫上的代碼是統(tǒng)一規(guī)范的。(當然,如果認為將這些配置文件都刪了,那也是沒辦法的)
 

總結(jié)

本文介紹了 ESLint 在中小型前端團隊的一些最佳實踐的想法,大家可以在此基礎上擴展,制訂一套完善的 ESLint 工作流,落地到自己團隊中。

分享到:

最熱資訊

熱門標簽