React-Native (JavaScript)代碼規范及檢測工具概述

在RN工程中,使用ESLint進行代碼規范掃描。

Why-- 為什么需要代碼規范

JavaScript的應用場景由最初的用在Web頁面中實現一些簡單交互,發展到處理復雜的網站功能交互等,甚至通過NodeJS來跑在服務端。應用的場景越來越多,越來越復雜,需要應對不同的運行的環境等,對代碼的穩定性和兼容性要求越來越高。

加上JavaScript語言本身存在一些設計缺陷,例如既是優點又是缺陷的弱類型特性、例如var變量的作用域問題等等,這些特性會帶來非常多的安全隱患。代碼不嚴謹可能就會觸發一些神奇的錯誤甚至一些低級錯誤,這些錯誤往往在編譯期間很難發現,通常只有在運行期間才會暴露出來,這樣很容易把問題帶到線上,導致面臨巨大的風險。以上問題,需要通過一套代碼規范機制來約束代碼風格、盡量避免低級錯誤的產生。

同時在企業的項目開發中,制定一套完善有效的編碼規范也是極為必要的。好的編碼習慣,規范的代碼風格對于降低團隊成員開發時的溝通成本、提升codeReview效率、提高代碼質量、提升系統穩定性等都是有巨大好處的。

在前端開發中有一些輔助工具來解決這個問題,例如JSLint、JSHint、ESLint等,其中現在比較流行且對JS新特性兼容比較好的是ESLint。這套機制同樣適用于React Native的開發.

What-- 規則、自動檢測工具(ESLint)

規則

工程目錄結構

以下目錄結構示例中只展示js與靜態資源,不包含原生代碼。

├── index.ios.js
├── index.android.js
└── js
    ├── component           可復用的組件(非完整頁面)
    ├── page                完整頁面
    ├── config              配置項(常量、接口地址、路由、多語言化等預置數據)
    ├── util                工具類(非UI組件)
    ├── style               全局樣式
    └── image               圖片

在component和page目錄中,可能還有一些內聚度較高的模塊再建目錄

page/component
├── HomeView.component.js
├── HomeView.style.js
└── MovieView
    ├── MovieList.component.js          
    ├── MovieList.style.js          
    ├── MovieCell.component.js          
    ├── MovieCell.style.js              
    ├── MovieView.component.js          
    └── MovieView.style.js              

代碼風格、規范

JavaScript基礎語法部分的代碼規范

ESLint內置的一套代碼規范(eslint:recommended):https://cn.eslint.org/docs/rules/

前端比較流行的一套代碼規范:Airbnb JavaScript Style Guide

React/JSX 相關的代碼規范

Airbnb React/JSX 風格指南:https://github.com/lin-123/javascript/tree/cn/react

自動檢測工具

JSLint、JSHint、ESLint對比

JSLint

2002 年,Douglas Crockford 開發了可能是第一款針對 JavaScript 的語法檢測工具 —— JSLint,并于 2010 年開源。

JSLint 面市后,確實幫助許多 JavaScript 開發者節省了不少排查代碼錯誤的時間。
但是 JSLint 的問題也很明顯:

  • 幾乎不可配置,所有的代碼風格和規則都是內置好的;
  • 再加上 JSLint 作者冷處理方式,不會向開發者妥協開放配置或者修改他覺得是對的規則。
JSHint

于是 Anton Kovalyov 吐槽:「JSLint 是讓你的代碼風格更像 Douglas Crockford 的而已」,并且在 2011 年 Fork 原項目開發了 JSHint。

JSHint 的特點就是:

  • 可配置,
  • 同時文檔也相對完善,
  • 而且對開發者友好。

很快大家就從 JSLint 轉向了 JSHint。

ESLint
ESLint 的誕生

起初幾年,JSHint 一直是前端代碼檢測工具的首選,包括 Nicholas C. Zakas 也是 JSHint 的用戶。但在 2013 年,Zakas 大佬發現 JSHint 已經無法滿足自己定制化規則的需求,而且和 Anton 討論后達成共識這根本在不可能在 JSHint 上實現。同時 Zakas 還設想發明一個基于 AST 的 lint,可以動態執行額外的規則,同時可以很方便的擴展規則。

2013 年的 6 月份,Zakas 發布了全新的 lint 工具——ESLint。

ESLint的特點:

  • 可擴展
  • 每條規則獨立
  • 可自定義規則

ESlint有一些內置的規則讓你更容易上手,同時你可以隨時加載自己的規則。

發展&契機

ESLint 的出現并沒有撼動 JSHint 的霸主地位。由于前者是利用 AST 處理規則,用 Esprima 解析代碼,執行速度要比只需要一步搞定的 JSHint 慢很多;其次當時已經有許多編輯器對 JSHint 支持完善,生態足夠強大。真正讓 ESLint 逆襲的是 ECMAScript 6 的出現。

ES2015

2015 年 6 月,ES2015 規范正式發布。但是發布后,市面上瀏覽器對最新標準的支持情況極其有限。如果想要提前體驗最新標準的語法,就得靠 Babel 之類的工具將代碼編譯成 ES5 甚至更低的版本,同時一些實驗性的特性也能靠 Babel 轉換。這時 JSHint 就略尷尬,ES2015 變化很大,短期內無法完全支持。ESLint 可擴展的優勢一下就體現出來了,不僅可以擴展規則,甚至連解析器也能替換。Babel 團隊就為 ESLint 開發了 babel-eslint 替換默認解析器,讓 ESLint 率先支持 ES2015 語法。

React&JSX

也是在 2015 年,React 的應用越來越廣泛,誕生不久的 JSX 也愈加流行。ESLint 本身也不支持 JSX 語法。還是因為可擴展性,eslint-plugin-react[10] 的出現讓 ESLint 也能支持當時 React 特有的規則。

至此,ESLint 完美躺贏,替代 JSHint 成為前端主流工具

How--在RN項目中如何利用ESLint實現高效的代碼規范校驗

ESLint的安裝

你可以使用 npm 安裝 ESLint,在JS工程的根目錄下執行:

$ npm install eslint --save-dev

緊接著你應該設置一個配置文件(初始化):

$ ./node_modules/.bin/eslint --init

之后,你可以在任何文件或目錄上運行ESLint如下:

$ ./node_modules/.bin/eslint yourfile.js

也可以在全局而不是本地安裝 ESLint (使用 npm install eslint --global)。但是,你使用的任何插件或可共享配置都必須安裝在本地。

ESLint的配置

運行 eslint --init 之后,.eslintrc 文件會在你的文件夾中自動創建(文件格式可以是“.js”、“.json”等)。例如一個.eslintrc.json文件內容如下:

{
    "env": {
        "browser": true,
        "es6": true,
        "react-native/react-native": true
    },
    "parser": "babel-eslint",
    "extends": [
        "eslint:recommended",
        "airbnb",
        "plugin:react-native/all",
        "plugin:flowtype/recommended"
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 6,
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "react-native",
        "flowtype"
    ],
    "rules": {
        "react/jsx-filename-extension": "off",
        "no-use-before-define": "off",
        "react-native/sort-styles": "off",
        "arrow-body-style": "off",
        "indent": "off",
        "react/jsx-indent": "off"
    }
}

parser:解析器

如前述,ESLint支持替換默認解析器。當代碼中用到了一些比較新的語法特性(例如需要Babel轉換的一些新特性或實驗特性)時,就需要使用一些其他的解析器,例如babel-eslint。

當然使用的前提是先在本地安裝對應的解析器,例如:

npm install eslint babel-eslint --save-dev

安裝后在配置文件中,設置對應的parser字段為自定義的解析器。(這里設置的為babel-eslint)

"parser": "babel-eslint",

extends:繼承

    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "airbnb",
        "plugin:react-native/all",
        "plugin:flowtype/recommended"
    ],

可以繼承一些現有的規則配置(規則集合),例如ESLint內置的推薦規則集(eslint:recommended),還有一些流行的第三方配置(例如:airbnb)或者第三方插件中的配置(例如:plugin:react/recommended)等。

  • 可以指定繼承多個配置
  • 繼承的配置可以是內置配置,例如:"eslint:recommended"
  • 可以是第三方配置包中的配置(例如eslint-config-airbnb),可以省略包名的前綴 eslint-config-,例如:"airbnb"
  • 也可以是第三方插件中的配置, extends 屬性值可以由以下組成:(例如"plugin:react/recommended")
    • plugin:
    • 包名 (省略了前綴,比如,react)
    • /
    • 配置名稱 (比如 recommended)
  • 繼承按順序依次繼承,如果有相同規則的設置,后面的會覆蓋前面的

plugins:插件

ESLint 支持使用第三方插件。在使用插件之前,你必須使用 npm 安裝它。

在配置文件里配置插件時,可以使用 plugins 關鍵字來存放插件名字的列表。插件名稱可以省略 eslint-plugin- 前綴。

注意:插件是相對于 ESLint 進程的當前工作目錄解析的。換句話說,ESLint 將加載與用戶通過從項目 Node 交互解釋器運行 ('eslint-plugin-pluginname') 獲得的相同的插件。

當你需要自定義一些ESLint沒有提供規則的時候就需要用的插件,可以通過自定義或者使用別人開發好的插件來加入一些新的代碼規則。

配置包(eslint-config-) VS 插件(eslint-plugin-)
相同點
  • 都是 npm 包
  • 都可以共享,通過npm可以安裝別人分享的包
  • 都可以對ESLint默認的規則進行設置
  • 都可以提供規則集(配置)
不同點
  • 配置包(eslint-config-),只是對已有規則的修改、聚合等
  • 插件(eslint-plugin-),也可以提供配置,同時可以新增自定義規則

rules:規則

可以在rules中添加一些額外的規則(除extends繼承的配置中啟用的),或者對extends引入的規則進行二次定制。

  • 規則啟用狀態設置:要改變一個規則設置,你必須將規則 ID 設置為下列值之一:

    • "off" 或 0 - 關閉規則
    • "warn" 或 1 - 開啟規則,使用警告級別的錯誤:warn (不會導致程序退出)
    • "error" 或 2 - 開啟規則,使用錯誤級別的錯誤:error (當被觸發的時候,程序會退出)
  • 額外選項設置:如果一個規則有額外的選項,你可以使用數組字面量指定它們,比如:

    {
        "rules": {
            "quotes": ["error", "double"]
        }
    }
    

"quotes": ["error", "double"] 為規則 quotes 指定了 “double”選項(雙引號)。數組的第一項總是規則的嚴重程度(數字或字符串)。

  • 配置定義在插件中的一個規則的時候,你必須使用 插件名/規則ID 的形式。比如:

    "rules": {
            "react/jsx-filename-extension": "off",
            "react/jsx-indent": "off"
     }
    

    注意:當指定來自插件的規則時,確保刪除 eslint-plugin- 前綴。ESLint 在內部只使用沒有前綴的名稱去定位規則。

ESLint與開發環境(工具)集成

WebStorm

  1. 進入ESLint設置:Preferences -> Languages & Frameworks -> JavaScript-> Code Quality Tools -> ESLint
  2. 選擇 Menual ESlint configuration
  3. ESlint package 設置為全局路徑(如果是本地安裝,選擇本地路徑):/usr/local/lib/node_modules/eslint
  4. Configuration file 路徑手動設置為項目 eslint 配置文件的路徑,例如:/Users/xxx/Documents/work_6/JD_Recharge/RN_Recharge/jdreact-jsbundle-jdreactrechargemodule/.eslintrc.json
webstorm設置

設置好以后,WebStorm就會自動檢測工程中的代碼,并會在發現的錯誤(或不符合規范)處進行波浪線標注,例如:

Tips

1.sourceType 是什么意思?

sourceType 有兩個值,script 和 module。 對于 ES6+ 的語法和用 import / export 的語法必須用 module.

2. eslint --init

只有在選擇 "To check syntax, find problems, and enforce code style" 才可以選擇 airbnb, standard, recommended 標準。

3. 環境

有時候在前端項目中存在前端和 node 的代碼共存的情況,只要在 env 中配置好 browser: true, node: true 就可以把兼容不同環境的全局變量兼容進來,例如 nodejs 中的 global, process 等等。

4. 常見規則強度

規則強度是 airbnb > standard > recommended. 看下圖,

recommended 和 standard 大概有 88 出不同,主要是 recommended 很多都是 off, standard 是 error, 同時 standard 還有很多特有的規則。

左邊是 recommended, 右邊是 standard
standard 特有的規則

5. 關于自動修復

現在代碼都比較嚴格,可能包含縮進是 2 個空格,是否在語句最后加逗號的情況。不可能自己手動去一個個修正。

eslint ./src --fix 

加上 --fix 可以自動修正一些明顯的問題。

參考:

前端工具考 - ESLint 篇:ESLint的誕生和發展

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,013評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,346評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,421評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,146評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,534評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,767評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,318評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,074評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,258評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,486評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,916評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,156評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,993評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,234評論 2 375