從0到1開發一個簡單的 eslint 插件

image.png

前言:eslint咱們常應用在代碼靜態掃描中,經過設定的eslint的語法規則,來對代碼進行檢查,經過規則來約束代碼的風格,以此來提升代碼的健壯性,避免由於代碼不規範致使應用出現bug的可能。而規則是自由的,你能夠設定內部本身團隊適用的規則,也能夠直接使用開源社區比較熱門的 規則集合, 好比airbnb、eslint-plugin-vue等

1.eslint的配置

手寫規則前,讓咱們重溫下eslint配置,一般咱們是使用 .eslintrc.js來配置eslint的,或者也能夠直接 package.json中定義eslintConfig的屬性

image.png

上圖👆是eslint主要的配置,咱們簡單回顧下每一個配置的背後包含的意義前端

1.1 parse

parse 是用來定義eslint所使用的解析器,默認是使用 Espree 🔗, 解析器的做用是將代碼code轉化成爲一種AST抽象語法樹,eslint中叫 ESTree,你能夠理解爲將code翻譯爲 ESLint能聽👂懂的話

關於Espree能夠參考下面這個例子vue

image.png

而經常使用的解析器還有包括如下幾種node

  • Esprima: 上文提到espree就是基於Esprima改良的
  • Babel-esLint:一個對Babel解析器的包裝,當你項目中使用了babel,babel的解析器會把你的code轉換爲 AST,而後該解析器會將其轉換爲ESLint能懂的 ESTree。這個目前咱們應用的較多,目前也再也不維護和更新,升級爲@babel/eslint-parser
  • @typescript-eslint/parser: 將 TypeScript 轉換成與 estree 兼容的形式,以便在ESLint中使用。

對於AST的模擬生成,感興趣的同窗可使用astexplorer在線嘗試react

image.png

總結:不管你使用那種解析器,本質是都是爲了將code轉換爲ESLint可以閱讀的語言ESTree🔗git

1.2 parseOption

parserOptions參數是用來控制parse解析器, 主要包括如下幾個屬性👇,咱們挑重點的講講

image.png

  • ecmaVersion:用來指定你想要使用的 ECMAScript 版本,默認設置爲 5,舉個例子:默認狀況下,ESLint 支持 ECMAScript 5 語法,但若是你想讓eslint使用es6特徵來支持,就能夠經過修改parserOptions中"ecmaVersion": 6

1.3 rules

rules就是eslint的規則,你能夠在rules配置中根據在不一樣場景、不一樣規範下添加自定義規則

1.4 extends(擴展) 與 plugins(插件)

extends和plugins很容易混淆,本質是爲了增強eslint的擴展性,使得咱們能夠直接使用別人已經寫好的eslint 規則,方便快捷的應用到項目中

好比你使用extends去擴展 { "extends": [ "eslint:recommended", "plugin:react/recommended", "eslint-config-standard", ]}es6

可是若是你想用插件,其實等價於 {"plugin": ['react','standard']}github

⏰ 提醒:官方規定 npm 包的擴展必須以 eslint-config- 開頭,咱們使用過程當中能夠省略這個開頭,上面案例中 eslint-config-standard 能夠直接簡寫成 standard。一樣,若是要開發一個eslint插件,也是須要以這種形式來命名,下節會介紹typescript

咱們再舉個列子npm

image.png

上圖咱們經過上面這個配置例子,咱們能夠看到要麼是plugins:[]要麼是extends:[],經過上圖所示的配置二相對於配置一少了parser, parserOptionsplugins 等的信息配置,但其實這兩個配置最終實現的結果是一致的,這是由於配置二中定義的extends:plugin:@typescript-eslint/recommended 會自動加載上敘提到的其餘幾個配置信息json

2 開發eslint插件

經過上一節對eslint的配置的瞭解,接下來看看如何從0到1開發一個eslint插件。

2.1 eslint插件初始化

ESLint 官方爲了方便開發者,提供了使用Yeoman腳手架的模板( generator-eslint🔗)。以此方便咱們經過該腳手架拉取eslint插件模版,對Yeoman 進一步瞭解能夠閱讀🌲樹醬的 前端工程化那些事 - yeoman

image.png

  • 第一步:安裝 npm install -g yo generator-eslint
  • 第二步:建立一個文件夾並而後經過命令行初始化ESLint插件的項目結構 yo eslint:plugin
  • 第三步:完成插件初始化建立

2.2 建立rule規則

完成插件項目結構初始化建立後,開始生成ESLint插件中具體規則,在ESLint插件的項目中執行命令行 yo eslint:rule,來生成eslint規則的模版,實際效果以下所示

image.png

建立成功後,咱們看下最終的目錄結構

image.png

  • docs: 使用文檔,描述你編寫的規則
  • lib/rules 目錄:規則開發源碼文件 (例如,no-extra-semi.js)
  • tests/lib/rules 目錄: 單元測試文件 (例如,no-extra-semi.js)

2.3 編寫規則

當完成上面一系列操做以後,eslint插件模版初步完成,接下來咱們找到目錄中 lib/rules中對剛剛建立的rule進行開發

假設咱們有個場景,咱們想建立一個規則,用來判讀代碼中是否存在console方法的調用,首先回到第一節提到的parse解析器,本質上rule的邏輯判斷是經過識別Espree返回的抽象語法🌲去判斷,分別針對各類類型定義檢查方法。寫代碼以前,咱們先看下console返回的AST是長啥樣?

image.png

經過上圖咱們能夠清晰的看到 console.log()是屬於 ExpressionStatement(表達式語句)中的 CallExpression(調用語句),能夠經過callee屬性中的object來判斷是否爲console, 同時也能夠利用其property屬性來判斷是console的哪一種方法,好比loginfo

so~ 咱們開始造玩具,咱們經過在 create 返回的對象中,定義一個 CallExpression 方法,當ESLint開始對esTree遍歷時,經過對調用語句的監聽,來檢查該調用語句是否爲 console 調用,代碼以下👇

image.png

每條 rule 就是一個 node 模塊,其主要由 meta 和 create 兩部分組成,重點講下下面兩個👇

  • meta: 表明了這條規則的元數據,包含類別,文檔,可接收的參數的 schema 等, 其中主要提下schema,若是指定該選項,ESLint能夠經過識別的傳參,避免無效的規則配置(排除校驗),可參考下節介紹的單元測試的中傳遞的options
  • context.report():它用來發布警告或錯誤(取決於你所使用的配置)

🌲 推薦閱讀:

2.4 單元測試

當完成eslit插件開發後,咱們須要對開發完的插件進行驗證,以此來保證規則校驗功能的正常使用。eslint插件開發項目結構中默認使用了 mocha做爲單元測試框架

咱們對tests/rules/treegogo.js單元測試文件進行修改,定義invalid與valid的不一樣例子

image.png

最後執行
image.png

2.5 關於發佈

在發佈以前,還須要對packjson中main定義入口文件即 lib/index.js,暴露出rules與configs

image.png

👨‍🎓 啊寬同窗:那我如何定義一個包含配置的集合呢?

是的,官方文檔描述:你能夠在一個插件中在 configs 鍵下指定打包的配置。當你想提供不止代碼風格,並且但願提供一些自定義規則來支持它時,會很是有用。每一個插件支持多配置,而後當你使用的時候,能夠經過這樣使用 `{

"extends": ["plugin:tree-eslint/myConfig"]

}, `這就包含預設好的規則配置

最後是npm發佈 npm pulish

2.6 如何使用

經過第一節的配置的介紹,咱們須要有個 .eslintrc文件,若是目錄沒用能夠經過命令行 eslint -init初始化,配置好後,安裝剛剛開放好的eslint插件

配置一能夠對咱們開發的那個rule 進行配置:error,warn,off,若是須要對部分作排除就加上option,也能夠像配置二引用預設好的擴展extends

image.png

你好,我是🌲 樹醬,請你喝杯🍵 記得三連哦~

1.閱讀完記得點個贊哦,有👍 有動力

2.關注公衆號前端那些趣事,陪你聊聊前端的趣事

3.文章收錄在Github frontendThings 感謝Star✨

相關文章
相關標籤/搜索