ESLint func-name-matching:迷ったらコレ!おすすめの設定とサンプルコード集

2024-06-08

ESLint の "func-name-matching" ルールとは?

ルール設定

このルールは、以下の 3 つの設定オプションを持つことができます。

  • "always" (デフォルト): すべての関数表現に名前を付ける必要があります。
  • "never": 名前付きの関数表現を許可しません。ただし、再帰関数など、名前が必要な場合は例外です。
  • "as-needed": 関数名が自動的に割り当てられない場合、関数表現に名前を付ける必要があります。

オプション

  • considerPropertyDescriptor: プロパティ記述子の名前も考慮します。
  • includeCommonJSModuleExports: CommonJS モジュールエクスポートも考慮します。

以下のコードは、"always" 設定で func-name-matching ルールを有効にした場合にエラーが発生します。

const greet = function() {
  console.log('Hello!');
};

greet();

このコードを修正するには、関数に名前を付けます。

const greet = function hello() {
  console.log('Hello!');
};

greet();

利点

  • コードの可読性と理解しやすさを向上させます。
  • 変数と関数の意図を明確にします。
  • コードのデバッグを容易にします。


ESLint の "func-name-matching" ルールに関するサンプルコード

ルール設定による動作の変化

設定: always

function greet() {
  console.log('Hello!');
}

greet();

結果: 問題なし

設定: never

function greet() {
  console.log('Hello!');
}

greet();

結果: エラー

設定: as-needed

function greet() {
  console.log('Hello!');
}

greet();
(() => {
  console.log('Hello!');
})();

オプションによる動作の変化

以下のコードは、func-name-matching ルールのオプションによって動作がどのように変化するかを示しています。

オプション: なし

const obj = {
  greet() {
    console.log('Hello!');
  }
};

obj.greet();

オプション: considerPropertyDescriptor

const obj = {
  greet() {
    console.log('Hello!');
  }
};

obj.greet();

オプション: includeCommonJSModuleExports

// CommonJS モジュール
module.exports = function greet() {
  console.log('Hello!');
};

その他の例

  • 再帰関数
function factorial(n) {
  if (n === 0) {
    return 1;
  } else {
    return n * factorial(n - 1);
  }
}
  • 匿名関数
const numbers = [1, 2, 3, 4, 5];
const filteredNumbers = numbers.filter(function(number) {
  return number % 2 === 0;
});

これらのサンプルコードは、func-name-matching ルールがどのように動作するかを理解するのに役立ちます。このルールは、コードの可読性と理解しやすさを向上させるための強力なツールです。



"func-name-matching" ルールの代替方法

  • arrow-body-style: アロー関数の本体に中括弧を強制します。
  • id-match: 変数名と関数名のあいだで一致を強制します。

これらのルールは、func-name-matching ルールと同様の目的を達成するために使用できますが、それぞれ異なる利点と欠点があります。

コメント

関数名の代わりに、コメントを使用して関数の目的を説明することができます。

// ユーザーを挨拶する関数
function greet(user) {
  console.log(`Hello, ${user}!`);
}

greet('Alice');

コメントは、自己文書化の優れた方法ですが、コードが冗長になる可能性があります。

ドキュメンテーション

関数の詳細な説明は、ドキュメンテーションツールを使用して記述することができます。

/**
 * ユーザーを挨拶する関数
 *
 * @param {string} user ユーザー名
 */
function greet(user) {
  console.log(`Hello, ${user}!`);
}

greet('Alice');

ドキュメンテーションは、関数の詳細な説明を提供するのに役立ちますが、メンテナンスが大変になる可能性があります。

命名規則

コードベース内で一貫した命名規則を使用することで、関数名を推測しやすくなります。

function greetUser(user) {
  console.log(`Hello, ${user}!`);
}

function calculateTotal(items) {
  let total = 0;
  for (const item of items) {
    total += item.price;
  }
  return total;
}

命名規則は、コードの可読性を向上させるのに役立ちますが、すべてのケースで適用できるとは限りません。

型システム

TypeScript などの型システムを使用すると、関数の型を定義することができます。これにより、関数の引数と戻り値が明確になり、関数名を推測しやすくなります。

function greetUser(user: string): void {
  console.log(`Hello, ${user}!`);
}

function calculateTotal(items: Product[]): number {
  let total = 0;
  for (const item of items) {
    total += item.price;
  }
  return total;
}

型システムは、コードの堅牢性を向上させるのに役立ちますが、学習曲線が険しい場合があります。

func-name-matching ルールにはいくつかの代替方法がありますが、それぞれ異なる利点と欠点があります。最良の代替方法は、特定のプロジェクトのニーズによって異なります。