ESLint の "no-implicit-globals" ルールとは?


ESLint の "no-implicit-globals" ルールとは?

このルールは、主に ブラウザスクリプト で問題となります。なぜなら、ブラウザスクリプトでは、トップレベルで宣言された変数や関数は、自動的にグローバル変数になってしまうからです。一方、ES モジュールや CommonJS モジュールでは、モジュールスコープと呼ばれる独自のスコープを持つため、この問題は発生しません。

no-implicit-globals ルールを有効にすると、以下の状況で警告またはエラーが発生します。

  • グローバル変数の宣言: var foo = 1; のように、var キーワードを使用してグローバル変数を宣言した場合。
  • グローバル関数宣言: function bar() {} のように、関数宣言をトップレベルで行った場合。
  • 読み取り専用グローバル変数の再宣言: window.location = "https://www.example.com"; のように、読み取り専用グローバル変数を再宣言したり、値を代入したりした場合。

no-implicit-globals ルールを有効にする利点は以下の通りです。

  • 意図しないグローバル変数の作成を防ぐ: 変数がグローバル変数であることを明確にすることで、意図しないグローバル変数の作成を防ぎ、コードの読みやすさとメンテナンス性を向上させることができます。
  • 名前空間の衝突を防ぐ: グローバル変数の使用を制限することで、異なるライブラリやモジュールで同じ名前の変数が定義されることによる名前空間の衝突を防ぐことができます。
  • セキュリティ上の脆弱性を防ぐ: グローバル変数の使用を制限することで、悪意のあるコードがグローバル変数を操作してセキュリティ上の脆弱性を悪用するのを防ぐことができます。

no-implicit-globals ルールを有効にするには、.eslintrc ファイルに以下の設定を追加する必要があります。

{
  "rules": {
    "no-implicit-globals": ["error"]
  }
}

この設定により、no-implicit-globals ルールが "error" レベルで有効になり、違反が見つかった場合、エラーとして報告されます。

no-implicit-globals ルールは、グローバル変数の使用を完全に禁止するものではありません。どうしてもグローバル変数を使用する必要がある場合は、以下の方法で例外を指定することができます。

  • グローバルオブジェクトに明示的にプロパティを追加する: window.myGlobalVar = 1; のように、グローバルオブジェクトに明示的にプロパティを追加することで、そのプロパティをグローバル変数として使用することができます。
  • /*global */ コメントを使用する: /*global myGlobalVar */ function foo() { ... } のように、関数の冒頭に /*global */ コメントを追加することで、その関数内で使用される変数をグローバル変数として宣言することができます。

no-implicit-globals ルールは、特にブラウザスクリプト開発において、コードの品質とセキュリティを向上させるために役立つ強力なツールです。グローバル変数の使用を制限することで、コードをより読みやすく、メンテナンスしやすく、安全にすることができます。

  • no-implicit-globals ルールは、JavaScript コードにおけるグローバル変数の使用を制限するための ESLint ルールです。
  • このルールは、主にブラウザスクリプトで問題となります。
  • no-implicit-globals ルールを有効にする利点は、意図しないグローバル変数の作成の防止、名前空間の衝突の防止、セキュリティ上の脆弱性の防止などです。
  • グローバル変数の使用を完全に禁止するものではなく、例外を指定することができます。
  • [最近は ESLint をいじって遊んでるので


エラーが発生するコード

// グローバル変数の宣言
foo = 1;

// グローバル関数宣言
function bar() {
  console.log('baz');
}

// 読み取り専用グローバル変数の再宣言
window.location = 'https://www.example.com';

以下のコードは、no-implicit-globals ルールによってエラーが発生しません。

グローバルオブジェクトに明示的にプロパティを追加する

// グローバルオブジェクトにプロパティを追加
window.myGlobalVar = 1;

console.log(myGlobalVar); // 1 を出力

**2. /global / コメントを使用する

/*global bar */
function foo() {
  bar(); // エラーが発生しない
}

foo();

var キーワードを使用せずに変数を宣言する

// let キーワードを使用して変数を宣言
let foo = 1;

console.log(foo); // 1 を出力

ES モジュールまたは CommonJS モジュールを使用する

// ES モジュールを使用
export function foo() {
  console.log('baz');
}

// CommonJS モジュールを使用
module.exports = function foo() {
  console.log('baz');
};

これらの例は、no-implicit-globals ルールをどのように使用して、グローバル変数の使用を制御できるかを示しています。

no-implicit-globals ルールは、さまざまな状況で使用することができます。以下に、いくつかの例を示します。

  • 外部ライブラリで使用されているグローバル変数へのアクセス: 多くの外部ライブラリは、グローバル変数を使用して機能を提供します。no-implicit-globals ルールを使用して、これらの変数へのアクセスを明示的に許可することができます。
  • テストコードでのグローバル変数の使用: テストコードでは、グローバル変数を使用してテスト環境を設定することがよくあります。no-implicit-globals ルールを使用して、テストコードでのみグローバル変数を使用できるようにすることができます。
  • 特定のグローバル変数の使用禁止: 特定のグローバル変数が使用されるのを禁止したい場合は、no-implicit-globals ルールと合わせて、/*eslint-disable no-implicit-globals */ コメントと /*eslint-enable no-implicit-globals */ コメントを使用することができます。


"no-implicit-globals" の代替方法

no-implicit-globals ルールの代替方法としては、以下の選択肢が考えられます。

ルールを無効にする

最も簡単な方法は、no-implicit-globals ルールを無効にすることです。これにより、グローバル変数を自由に使用することができます。ただし、この方法を選択すると、意図しないグローバル変数の作成や名前空間の衝突などの問題が発生する可能性が高くなります。

例外を指定する

特定のグローバル変数のみを許可したい場合は、no-implicit-globals ルールで例外を指定することができます。これを行うには、.eslintrc ファイルに以下の設定を追加します。

{
  "rules": {
    "no-implicit-globals": ["error", {"allow": ["jQuery", "$"]}]
  }
}

代替のコーディングスタイルを使用する

  • ES モジュールまたは CommonJS モジュールを使用する: ES モジュールや CommonJS モジュールは、モジュールスコープと呼ばれる独自のスコープを持つため、グローバル変数の問題が発生しません。
  • let キーワードまたは const キーワードを使用して変数を宣言する: let キーワードまたは const キーワードを使用して変数を宣言すると、その変数はブロックスコープを持ち、グローバル変数になりません。
  • Arrow 関数を使用する: Arrow 関数は、暗黙的にグローバル変数をキャプチャしないため、グローバル変数の問題が発生する可能性が低くなります。

別の ESLint ルールを使用する

no-implicit-globals ルール以外にも、グローバル変数の使用を制御する ESLint ルールがいくつかあります。以下に、いくつかの例を示します。

  • no-var: var キーワードの使用を禁止するルールです。
  • no-undef: 未定義の変数の使用を禁止するルールです。
  • no-unused-vars: 使用されていない変数の使用を禁止するルールです。

これらのルールを組み合わせて使用することで、より効果的にグローバル変数の使用を制御することができます。

適切な代替方法の選択

no-implicit-globals ルールの代替方法を選択する際には、以下の点を考慮する必要があります。

  • プロジェクトの要件: プロジェクトの要件によっては、グローバル変数の使用が不可欠な場合があります。
  • コードベースの規模と複雑さ: コードベースが大きくて複雑な場合は、no-implicit-globals ルールを無効にするよりも、例外を指定したり、代替のコーディングスタイルを使用したりする方がよい場合があります。
  • チームのコーディング慣習: チーム内で統一されたコーディング慣習を維持することが重要です。