🤔

.eslintrcのenv設定ってなんぞや?

2021/06/24に公開
.eslintrc.json
{
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  ...
}

こんな設定を書いていると思いますが、envとはなんなのか理解せずいれていたので調べてみました。
これまであいまいにenv設定をしていた人はぜひみてください。

公式ドキュメント

https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments

An environment provides predefined global variables.

とのことなので、envはあらかじめ用意されているグローバル変数を設定しておくものらしいです。
おそらくbrowserだったらalertとかwindowとかあるんだろうなとちょっと想像できるわけですが、実際にはなにが設定されてされているのでしょうか。

しかしそのリンクや情報は公式ドキュメントにはない。。。 のでソースコードを追ってみたところ、設定されている場所を見つけることができました。

https://github.com/eslint/eslintrc/blob/main/conf/environments.js

そして細かい設定はこちらのglobalsというパッケージが利用されています。

https://github.com/sindresorhus/globals/blob/main/globals.json

たとえばbrowserであればこのあたりです。

{
	...
	"browser": {
		"AbortController": false,
		"AbortSignal": false,
		"addEventListener": false,
		"alert": false,
		"AnalyserNode": false,
		"Animation": false,
    		...

ちなみにこのfalseはreadonly(変更不可)という意味で、readonlyなのにソースコード上で書き換えているような箇所があればエラーとなります。(参考)
逆にtrueはwritableです。

どういうときに役に立つのか?

例えばこんなコードがあったとします。

window.onload = function() {
  alert('hello world!');
};

これはブラウザ上では問題なく動作しますが、ESLintはブラウザ上で動くものではないためwindowalertも変数定義もなくいきなり呼び出されていて、 こいつはけしからん!定義されてない変数を使っていて動かないコードだ! と認識されるわけです。

そのために.eslintrcにglobalsという設定を入れておくことにより、これらはグローバルに定義されている変数だからいきなり使ってよいという設定をすることができます。

.eslintrc.json
{
  "globals": {
    "window": false,
    "alert": false
  }
}

ただブラウザにはたくさんのグローバル変数があり、それらを使うたびにglobals設定を追加していくのは大変です。

そこでenv設定にbrowserをいれることによりwindowalertも含まれるたくさんのブラウザ用のグローバル変数を一気にglobals設定に登録してしまい、ESLintにチェックしなくてよいと伝えることができます。

.eslintrc.json
{
  "env": {
    "browser": true  // たくさんのglobals設定が登録された!
  }
}

ESlintのno-undefルールに関連する

https://eslint.org/docs/rules/no-undef

no-undefルールは、宣言されていない変数を利用しようとしたときにエラーになるルールです。ただし、globals設定されているものに対してはグローバルに定義されていると認識されるためエラーになりません。

.eslintrc.json
{
  "env": {
    "browser": true
  },
  "rules": {
    "no-undef": "error"
  }
}

の設定の場合、

alert('hello');  // alert はglobalsに入っているのでエラーにならない
hoge();          // hoge はglobalsにはないためエラーになる

となります。.eslintrcでeslint:recommendedをextendsした場合もno-undefは errorになっています
no-undefルールを手動でoffにしている場合はhoge()もエラーになりません。

TypeScript利用時はno-undefルールはoffにする

理由は以下に記載していました。
https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors

TypeScriptはグローバルに変数が使われていても型チェックで存在するかどうかが判定できるから、ESLintでチェックしなくても基本は大丈夫ですよ、ということです。

たとえばwindowであればtsconfig.jsonに"lib": ["dom"],をいれておくことでwindow変数はTypeScriptに定義されます

.eslintrcのextends設定にplugin:@typescript-eslint/recommendedを入れていた場合もno-undefルールはoffになっています。

https://github.com/typescript-eslint/typescript-eslint/blob/8cfe93372e1d826e54febc3aeb7047c792b90963/packages/eslint-plugin/src/configs/eslint-recommended.ts#L24

ですので、TypeScriptを使っていてplugin:@typescript-eslint/recommendedをextendsしている場合は、ESLintでグローバル変数のチェックはしないためenv設定は必要ないかもしれません。


ということで、envとglobalsについて説明していきました。
私みたいによく理解せずenv設定していた人は一度見直してみてください。

extends設定はこちらも見てみてね〜
https://zenn.dev/kimromi/articles/b7cf98005f3193

では快適なESLint生活を!

Discussion