O hirunewani blog

Q. 削除された変数への参照が、グローバル変数と一致しているためエラーが出ない

Created at

ESLintのno-restricted-globalsルールを利用することで、グローバル変数を禁止して、意図しないグローバル変数への参照を防ぐ。

Table of Contents

状況

まずeventという名前の引数を受け取る次のようなコンポーネントがあった。

const SomeComponent = ({ event }) => {
  return (
    <div>
      <Button
        onClick={() => {
          // eventを利用した処理
        }}
      >
        Click me
      </Button>
      {/* とても長いコード */}
    </div>
  );
};

次にclick eventを利用したくなり、次のように引数から受け取るeventをrenameした。

const SomeComponent = ({ someEvent }) => {
  return (
    <div>
      <Button
        onClick={event => {
          // someEventとeventを利用した処理
        }}
      >
        Click me
      </Button>
      {/* とても長いコード */}
    </div>
  );
};

このとき、変更箇所自体は想定通りの挙動をしていたが、それ以降のコードでeventという変数を利用している箇所が残っていた。

通常の変数であれば、このような参照があるとエラーが出るが、グローバル変数であるeventと重複していたためエラーが検出されなかった。

対応策

このような問題を防ぐために、ESLintのno-restricted-globalsルールを利用することができる。

https://eslint.org/docs/latest/rules/no-restricted-globals

{
  rules: {
    "no-restricted-globals": ["error", "event"]
  }
}

このルールで指定されたグローバル変数を利用する場合、明示的にglobalThis.eventのように指定しなければエラーが出るようになるため、意図しないグローバル変数への参照を防ぐことができる。

余談

no-restricted-globalsルールでeventという変数名は名指しで言及されている。

For instance, early Internet Explorer versions exposed the current DOM event as a global variable event, but using this variable has been considered as a bad practice for a long time. Restricting this will make sure this variable isn’t used in browser code. - https://eslint.org/docs/latest/rules/no-restricted-globals

このように歴史的な経緯などにより、ブラウザ環境には非常に多くのグローバル変数が存在し、中にはeventのように変数名が被ってしまいそうなものが複数存在する。

ESLintで利用するglobalsパッケージのbrowserフィールドを見ると、event以外にもerrorlengthnamestatustopなどが存在している。

https://github.com/sindresorhus/globals/blob/v15.11.0/globals.json#L29