• ..

CircleCI

    .eslintrc.js を eslint を使ってフォーマット

    .eslintrc.jsなどの自分の設定ファイルはデフォルトで除外設定になっているのか、そのままではエラーになります。これは--ignore-patternまたは--no-ignoreオプションを使ってそのコマンド中のみ解除できます。

    以下のように実行で動くはずです。

    yarn eslint --fix .eslintrc.js --ignore-pattern '!.eslintrc.js' 
    yarn eslint --fix .eslintrc.js --no-ignore # すべて解除

    独自のグローバル変数を許可する

    独自のグローバル変数とは、いきなりコード上に現れる本来のグローバルオブジェクト(windowなど)には存在しない値のことです。

    例えば以下のような場合に現れる可能性があります。

    • <script>の中のコードで変数定義で追加された値
    • Webpack のプラグイン(ProvidePlugin等)で定義された値

    これらで定義された値をいきなりコード上で使うと ESLint (eslint-loader)によりReferenceErrorが起こされる可能性があります。

    あるグローバル変数は許可させる

    これを直すには.eslintrcglobalsセクションを追加します。その値はオブジェクトを置き、構造は{グローバス変数名: true}のような形です。
    例えば、foobarというグローバル変数を許可したいなら

    {
      "globals": {
        "foo": true,
        "bar": true
      }
    }

    のような設定になります。

    対象のファイルで有効な設定を一覧する

    overridesセクションなどが複雑になってきていると、このファイルにちゃんとお目当ての設定が当たってるかデバッグしたくなる時があります。そんな時は CLI の--print-configオプションが使えます。

    CLI

    使い方は簡単で--print-config <対象のファイル名>という形で実行するだけです。

    eslint --print-config path/to/hogehoge.js
    # {
    #   "rules": [...],
    #   "plugins": [...]
    # }

    .eslintrc がネスト構造で複数配置されている場合どのように解決されるか

    確認したレベルでは「各セクション毎にマージされる」です。

    調べる

    例えばモノレポなどでルート.eslintrcを1つ置き、各ワークスペースにも.eslintrcを置いているとします。

    # tree
    .
    ├── ...
    ├── .eslintrc
    └── packages
        └── foo
            ├── ...
            └── .eslintrc

    ルートの設定

    ルートの設定は適当にこんな感じにしました。

    {
      "root": true,
      "env": {
        "browser": false,
        "node": false
      },
      "rules": {
        "no-unused-vars": 0,
        "eqeqeq": 0
      }
    }

    ワークスペースの設定

    上記でのpackages/foo/.eslintrcをこのようにしました。

    {
      "env": {
        "node": true
      },
      "rules": {
        "no-unused-vars": 2
      }
    }

    さて、ここでpackages/foo以下のファイルへの設定は考えられるもので、

    • マージされる(完全に置き換わる)
    • 各セクションレベルでマージされる(ディープマージ)

    どれが正解なのかという疑問がでてきました。

    調べる

    対象のファイルへ適用される設定を調べるには--print-configオプションが使えます。

    ルートで、

    eslint --print-config packages/foo/foo.js

    結果はこうでした。(envrules以外のセクションは削除してます)

    {
      "env": {
        "browser": false,
        "node": true
      },
      "rules": {
        "no-unused-vars": 2,
        "eqeqeq": 0
      },
      "root": true
    }

    完全に置き換えたい

    そんな時は子.eslintrcroot:trueを追加します。実は ESLint はルート設定まで遡り設定をディープマージしていくような動作をします。これがroot:trueにより「自分自身ファイルがルートです」となることでで親設定を拾わず、それだけの設定にすることができます。

    {
      "root": true,
      "env": {
        "node": true
      },
      "rules": {
        "no-unused-vars": 2
      }
    }

    結果。

    {
      "env": {
        "node": true
      },
      "rules": {
        "no-unused-vars": 2
      },
      "root": true
    }