🐾

未経験がESLintのFlat Configについてまとめてみた

2023/06/01に公開

はじめに

本記事の概要

フロントエンドエンジニアを目指して学習中の私が、ESLint の Flat Config について学んだことをまとめた記事です

この記事でわかること

ESLint の新しい設定方法がこれまでよりとてもシンプルだということ

対象読者

「ESLint の設定は難しそうすぎてちょっと無理」と思っている方

ESLint とは何ですか?

ESLint is an open source project that helps you find and fix problems with your JavaScript code.

ESLint は、JavaScript のコードを静的に解析するためのツールです。

ESLlint をプロジェクトに導入することで、コードの構文エラーをチェックしたり、システム全体のコードの一貫性を維持することができます。

Flat Config とは何ですか?

ESLint's new config system, nicknamed flat config, is designed to be both familiar and much simpler than the original config system.

Flat Config とは、ESLint の新しい設定方法のことで、慣れ親しんだ方法であるとともにこれまでよりもはるかにシンプルである、とのことです。
俄然興味をそそられますね。

以下は、開発者によるブログです。
https://eslint.org/blog/2022/08/new-config-system-part-1/
https://eslint.org/blog/2022/08/new-config-system-part-2/
Part1 では ESLint のこれまでの進化と葛藤、そして Flat Config が誕生するに至った経緯が、part2 では Flat Config が何を目指したかがそれぞれ綴られています。
Google 翻訳そのまま、わからない部分はがっつり読み飛ばしましたが、それでも ESLint がどれだけ偉大なエンジニアたちによって開発されてきた素晴らしいツールであるかを垣間見ることができました。

新旧対象

ここからは設定方法の新旧について、私なりにまとめてみます

設定ファイルについて

【旧】

  • .eslintrcという名前の設定用ファイルを色々な形式で作成でき、いろんな場所に複数設置することができる
  • なんならpackage.json内でも設定できる
  • 複数のファイルで設定されたルールをどう優先して適用するかは、カスケードがどうのという何やら複雑な法則で決まる

【新】

  • eslint.config.jsファイルをルートディレクトリに1つだけ配置して、全部そこに記述する

【補足】

いきなりシンプルですね。

これまでの「設定ファイルをあちこちに作ってカスケードがどうのこうの」な部分は、ドキュメントを読んでみようとしましたが、残念ながら今の私に理解できる代物ではありませんでした。
一方、新しい設定ファイルは1つだけ。
がんばってドキュメントを読んでみようという気になれます。

ということで、以下、新しいeslint.config.jsファイルの概要です。

eslint.config.jsファイルでは、設定オブジェクトの配列をエクスポートします。
設定オブジェクトとは、ESLint が解析に必要なすべての情報を含んだもので、以下はその例です。

eslint.config.js
export default [
  // 設定オブジェクト
  {
    // どのファイルに適用するか
    files: ["src/**/*.js"],
    // どのファイルに適用しないか
    ignores: ["**/*.config.js"],
    // 適用するルール
    rules: {
      semi: "error",
    },
  },
];

eslint.config.jsファイルでは、デフォルトで .js, .mjs, .cjs形式のファイルすべてを解析の対象としています。
そして、設定オブジェクト内のルールを一部のファイルにのみ適用させたい場合には、filesで適用ファイルを指定でき、逆に適用させたくないファイルがある場合には、ignoresで除外ファイルを指定できます。

設定オブジェクト同士で設定が競合した場合には、競合した部分はあとから書いたもので上書きされます。

デフォルトの設定と JavaScript の評価方法について

【旧】

ECMAScript5(以下、「ES5」という。)をデフォルトとして、以下の項目によって JavaScript の評価方法を設定する。

  • env
  • parser
  • parserOptions
    • ecmaVersion
    • sourceType
    • allowReserved
    • ecmaFeatures
  • globals

【新】

ECMAScript の最新バージョンをデフォルトとして、以下の項目によって JavaScript の評価方法を設定する。

  • languageOptions
    • ecmaVersion
    • sourceType
    • parser
    • parserOptions
    • globals

【補足】

.eslintrcファイルでは ES5 がデフォルトでしたが、eslint.config.jsにおけるデフォルトは ECMAScript の最新バージョンです。

また、これまでバラバラだった JavaScript の評価に係る項目が整理され、languageOptionsにまとめられました。
languageOptionsの各項目の概要は、以下のとおりです。

  • ecmaVersion
    ESLint が JavaScript の評価に使用する JavaScript(ECMAScript)のバージョンを設定する項目
    指定された ecmaVersion で、構文とグローバル変数が有効になる
    デフォルトは"latest"
  • sourceType
    評価方法("module", "commonjs", "script")を設定する項目
    ファイルがどのようにパースされるか、ESLint がスコープ構造をどのように評価するかに影響する
    デフォルトでは、.jsファイル及び.mjsファイルに対しては"module"が、.cjsファイルに対しては"commonjs"が設定される
  • parser
    ESLint のパーサーをオーバーライドするための項目
  • parserOptions
    カスタムパーサーにオプションを渡すための項目
  • globals
    グローバル変数を設定するための項目

この辺を自分で設定するためには、JavaScript 自体をもっと勉強する必要がありそうです...

rules について

rulesについては、新旧で特に変更はありません。

【補足】

rules とはそのまま、JavaScript のコードを記述する際のルールです。

ESLint では、たとえば文末に;をつけるかどうかや、'"のどちらを使用するかといったコードを書く際のルールを、それぞれ無視するか(off)、警告を出すか(warn)、エラー扱いにするか(error)の 3 段階で設定できます。

ただし、ルールは ESLint に組込みのものだけで 200 以上あるため、これらをすべて 1 から設定することは推奨されていません。
実際に設定を行う際には、npm パッケージで公開されているすでに設定済みのファイルを活用することが一般的です(shareable configs)。

また、ESLint では、ESLint が推奨するルール一式を有効にするjs.configs.recommendedと、組込みのルールすベてを有効にするjs.configs.allが事前に定義されています。

eslint.config.js
import js from "@eslint/js";

export default [
    js.configs.recommended,
    {
        rules: {
            semi: ["warn", "always"]
        }
    }
];

plugin について

pluginについては、記述方法が以下のように変更されました。

eslint.config.js
import jsdoc from "eslint-plugin-jsdoc";

export default [
    {
        files: ["**/*.js"],
        plugins: {
            jsdoc
        }
        rules: {
            "jsdoc/require-description": "error",
            "jsdoc/check-values": "error"
        }
    }
];

【補足】

pluginとは、ルールを拡張するための項目です。

ESLint においては、組込みのルール以外にも多くのルールが npm パッケージによって提供されています。それらをインストールしてpluginに記述することで、追加のルールを設定できるようになります。
plugin に記述することにより「追加のルールが使えるようになる」というだけで、追加したルールを適用させるにはrulesで設定する必要があります)

pluginのエコシステムは ESLint にとって重要なものであるため、記述方法は変わりましたが、これまでと同様に使用できるようになっています。
なお、記述方法が変わったことによるメリットもあるようですが、ここではそこまで(理解できていないため)触れません。

extendsについて

【旧】

shareable configsを適用するためのextendsという項目があった

【新】

extendsが不要となり、削除された

【補足】

.eslintrcではextendsという項目を使用してshareable configsを適用していましたが、eslint.config.jsでは直接配列に挿入できるようになりました。

eslint.config.js
import customConfig from "eslint-config-custom";

export default [
    customConfig,
    {
        files: ["**/*.js", "**/*.cjs"],
        rules: {
            "semi": "error",
            "no-unused-vars": "error"
        }
    }
];

なお、後方互換性を確保するために@eslint/eslintrc からFlatCompatクラス が提供されており、.eslintrc形式のshareable configsも引続き使用することができます。

eslint.config.js
import { FlatCompat } from "@eslint/eslintrc";
import path from "path";
import { fileURLToPath } from "url";

// mimic CommonJS variables -- not needed if using CommonJS
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const compat = new FlatCompat({
    baseDirectory: __dirname
});

export default [

    // mimic ESLintRC-style extends
    ...compat.extends("standard", "example"),

    // mimic environments
    ...compat.env({
        es2020: true,
        node: true
    }),

    // mimic plugins
    ...compat.plugins("airbnb", "react"),

    // translate an entire config
    ...compat.config({
        plugins: ["airbnb", "react"],
        extends: "standard",
        env: {
            es2020: true,
            node: true
        },
        rules: {
            semi: "error"
        }
    })
];

その他の項目について

linterOptions, processor, settingsについては、これまでとまったく同じかほとんど変わらないとのことです。

おわりに

いかがでしたでしょうか。

私自身、これまで設定について理解しないまま ESLint を使用していましたが、今回、開発者のブログや Flat Config のドキュメントを読んでみてとても興味が湧きました。
いつか「ESLint、設定できますよ」と胸を張って言えるよう、精進したいと思います!

ここまで読んでいただきありがとうございました。

記事についてお気づきのことなどありましたら、コメントいただけますと大変うれしいです 🐾

参考記事

https://www.docswell.com/s/t__keshi/ZGXXV8-eslint-flat-config#p1
https://www.sunapro.com/eslint-flat-config
https://zenn.dev/babel/articles/eslint-flat-config-for-babel

Discussion