建置eslint開發環境

2018/03/18 posted in  nodejs comments

1. 前言

對於所有Project來說,"Coding Style"都很重要,尤其是多人協作時,應該大家一起follow某些共同的coding style,才方便互相查看及修改其他人的code。

這時候我們可以使用eslint,來規範整個project的code,雖不能統一各人的個人風格,但它可以確保所有code都consistently follow某些syntax,不會亂糟糟。

2. 建置流程

每個project的設定都不盡相同,以下以 React Native + Expo 的project作例子。

安裝eslint

$ yarn add eslint --dev
$ yarn add babel-eslint --dev  # 如果你有用babel (i.e. 有個.babelrc的config檔案)
  • 建議安裝eslint到project的node_modules/,而不是global environment
  • 我偏好使用yarn來安裝,你也可以使用npm install --save-dev
  • 使用--dev會安裝到package.json裡的devDependencies,代表只會在開發時用到,不會bundle進你的application

eslint: getting-started

題外話:babel

babel 是一個"Javascript compiler",在nodejs的project中很常見,一般需要用到 ES6 (ES2015) 的語法或功能時,
都會使用 babel compile回ES5的javascript,來確保舊browser也可以運行你的code。

初始化

安裝好後,首先要建立一個config檔來說明linter應如何運作。

$ ./node_modules/.bin/eslint --init
#  使用剛安裝的local eslint來執行

然後只需以interactive的形式答問題。以下是react-native+expo project的sample setup:

? How would you like to configure ESLint? Answer questions about your style
? Are you using ECMAScript 6 features? Yes
? Are you using ES6 modules? Yes
? Where will your code run? Browser, Node
? Do you use CommonJS? No
? Do you use JSX? Yes
? Do you use React? Yes
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Single
? What line endings do you use? Unix
? Do you require semicolons? Yes
? What format do you want your config file to be in? JavaScript  # 最好不要用JSON,因為不能加入comment

檢查

安裝好後package.json應該會有:

  • 一個.eslintrc.js檔案,這裡就是所有eslint的設定
module.exports = {
    "env": {
        "browser": true,
        "es6": true,
        "node": true
    },
    "extends": ["eslint:recommended", "plugin:react/recommended"],
    "parser": "babel-eslint",
    "parserOptions": {
        "ecmaVersion": 2017,
        "ecmaFeatures": {
            "experimentalObjectRestSpread": true,
            "jsx": true
        },
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
};
  • 和一堆新的dependencies
"devDependencies": {
  "babel-eslint": "^8.2.1",
  "babel-preset-expo": "^2.0.0",
  "eslint": "^4.15.0",
  "eslint-config-airbnb": "^16.1.0",
  "eslint-plugin-import": "^2.8.0",
  "eslint-plugin-jsx-a11y": "^6.0.3",
  "eslint-plugin-react": "^7.5.1"
}

3. 設置

執行

先嘗試執行eslint:

$ ./node_modules/.bin/eslint some_file.js
# 或
$ ./node_modules/.bin/eslint some_folder/

修改設定

先試試lint一些檔案,第一次一定有很多error出現,之後慢慢按自己的需要更改.eslintrc

例如我的error:

   2:8   error  'Expo' is defined but never used                no-unused-vars
   3:10  error  'AppLoading' is defined but never used          no-unused-vars
   4:8   error  'React' is defined but never used               no-unused-vars
   5:10  error  'Image' is defined but never used               no-unused-vars
   6:10  error  'Ionicons' is defined but never used            no-unused-vars
  11:8   error  'ReduxWrapper' is defined but never used        no-unused-vars
  26:10  error  'cacheFonts' is defined but never used          no-unused-vars
  27:1   error  Expected indentation of 4 spaces but found 2    indent
  35:1   error  Expected indentation of 4 spaces but found 2    indent
  36:1   error  Expected indentation of 8 spaces but found 4    indent
  37:1   error  Expected indentation of 8 spaces but found 4    indent
  38:1   error  Expected indentation of 12 spaces but found 6   indent
  39:1   error  Expected indentation of 8 spaces but found 4    indent
  40:1   error  Expected indentation of 4 spaces but found 2    indent
  42:1   error  Expected indentation of 4 spaces but found 2    indent
  43:1   error  Expected indentation of 8 spaces but found 4    indent
  43:5   error  Unexpected console statement                    no-console
  44:1   error  Expected indentation of 4 spaces but found 2    indent
  46:1   error  Expected indentation of 4 spaces but found 2    indent
  51:1   error  Expected indentation of 8 spaces but found 4    indent
  ...........

indent

我習慣使用2 spaces indent,把rules裡的indent改改

"rules": {
        "indent": [
            "error",  // 也可以改做"warn"
            2  // 2 spaces
        ],
        ...

no-unused-vars

React那些是never used也要import的,例如

import React, { Component } from 'react';  // 沒有import React會error

"extends": "eslint:recommended",

改成

"extends": ["eslint:recommended", "plugin:react/recommended"],  // 要確保有安裝"eslint-plugin-react"

no-console

"extends": "eslint:recommended" default啟用了no-console模式,不允許到處console.log()

最主要用途是避免user在browser看到開發用的debug message,但對於我的react-native project或一般node project其實是沒有所謂的。

rules裡面加入:

"no-console": 0,

Reference

其他

結果

最後還是有以下error:

   2:8   error  'Expo' is defined but never used        no-unused-vars
   5:10  error  'Image' is defined but never used       no-unused-vars
   6:10  error  'Ionicons' is defined but never used    no-unused-vars
  26:10  error  'cacheFonts' is defined but never used  no-unused-vars
  75:8   error  Missing semicolon                       semi
  79:6   error  Missing semicolon                       semi

這些就是真的需要fix的地方了。

4. Integrations

以上執行只是在command line run一次,實際工作流程中,不可能每次都自己run一下。

所以有各種integration support,讓developers可以在開發的過程中立即發現問題並及時修正。

Editor/IDE

在平日的開發editor中加入linter,即時在coding的時候知道哪裡有問題。

Sublime

  1. 安裝 Package Control (非常多人用,基本上是sublime必需工具)
  2. Command + Shift + P: "Install packages"
  3. 安裝SublimeLinter-eslint

Github: SublimeLinter-eslint

Reference

(其他language也可以使用Sublimelinter)

Build tools

Integrate進build tools可以在例如每次webpack build的時候、github deploy的時候lint一次,確保application build符合linting規則。

Reference