👏

graphql-eslintを導入してGraphQLをLintする with Flat Config

2023/10/10に公開

最近フロントエンドでGraphQLのLintを行うためにgraphql-eslintを導入したのですが、直近でFlat Configに移行したこともあり、いくつか詰まる箇所があったので導入方法を紹介したいと思います。

graphql-eslintとは

graphql-eslintとはThe Guildによって公開されているESLintのプラグインで、GraphQLのスキーマやオペレーションに対してLintを実行することができます。

https://the-guild.dev/graphql/eslint/docs

導入方法

簡単な導入方法といくつかのオプションについて紹介します。

下記コマンドでプラグインを追加します。

yarn add --dev @graphql-eslint/eslint-plugin

最小の構成の場合、設定は下記のようになります。

const esLintPluginGraphQL = require('@graphql-eslint/eslint-plugin');

module.exports = [
  {
    files: ['src/**/*.graphql'],
    languageOptions: {
      parser: esLintPluginGraphQL,
    },
    plugins: {
      '@graphql-eslint': esLintPluginGraphQL,
    },
    rules: {
      '@graphql-eslint/no-anonymous-operations': 'error',
    },
  },
];

Parser Options

動かすだけであれば上記で問題ないですが、実務で使用する場合はoperations-recommendedなどのルールセットを使用することになると思います。その中にはschemadocumentsなどのオプションを必要とするルールも存在するため、必要に応じてこれらのオプションを指定する必要があります。

schema

GraphQLスキーマのURLやファイルパスを指定します。
例えば@graphql-eslint/no-deprecatedなどのルールの場合、GraphQLスキーマの情報が必要になるので、このオプションを指定する必要があります。

documents

GraphQLオペレーションが定義されているファイルのパスを指定します。
ESLintは1ファイルずつチェックして行きます。しかし、Fragmentをファイルを跨いで使用している場合、単一ファイルだけでは情報が足りず、ルールが正しく適用されない可能性があります。
このオプションを指定することで、Lintする際に別ファイルのGraphQLオペレーションを参照でき、正しくルールが適用できるようになります。

その他にもオプションはありますが、公式ドキュメントは更新されていないので、実装を参照するのが良さそうです。

下記は上記のオプションを指定した上で、operations-recommendedを使用する場合の設定です。

const esLintPluginGraphQL = require('@graphql-eslint/eslint-plugin');

module.exports = [
  {
    files: ['src/**/*.graphql'],
    languageOptions: {
      parser: esLintPluginGraphQL,
      parserOptions: {
        schema: './graphql.schema.json',
        documents: ['src/**/*.graphql'],
      },
    },
    plugins: {
      '@graphql-eslint': esLintPluginGraphQL,
    },
    rules: {
      ...esLintPluginGraphQL.flatConfigs['operations-recommended'].rules,
    },
  },
];

ソースコード内でGraphQLオペレーションが定義されている場合

GraphQLオペレーションの定義を.graphqlファイルではなく、.ts.tsxなどのソースコード内で定義してる場合もあります。その場合はそれらのファイルに対してprocessorを指定する必要があります。
これにより、ソースコード内で定義されたGraphQLのスキーマやオペレーションを元に、仮想的な.graphqlファイルが生成されるようになります。この生成された仮想ファイルに対して、Lintを実行することで、ソースコード内で定義されたGraphQLオペレーションにもルールを適用することができるようになります。

実際の設定は下記の様になります。

const esLintPluginGraphQL = require('@graphql-eslint/eslint-plugin');
const tsEsLintParser = require('@typescript-eslint/parser');

module.exports = [
  {
    files: ['src/**/*.{ts,tsx}'],
    processor: esLintPluginGraphQL.processors.graphql,
    languageOptions: {
      parser: tsEsLintParser,
    },
  },
  {
    files: ['src/**/*.graphql'],
    languageOptions: {
      parser: esLintPluginGraphQL,
      parserOptions: {
        schema: './graphql.schema.json',
        documents: ['src/**/*.{graphql,ts,tsx}'],
      },
    },
    plugins: {
      '@graphql-eslint': esLintPluginGraphQL,
    },
    rules: {
      ...esLintPluginGraphQL.flatConfigs['operations-recommended'].rules,
    },
  },
];

まとめ

導入に当たり、プロセッサー周りなど地味に詰まる箇所があったので、同じようにgraphql-eslintの導入を検討している方の参考になれば幸いです。
また、ESLintのカスタムルールを作成するための機能も提供しており、実際に使用してカスタムルールを作成してみたので、それに関しては別途記事にしようと思います!

株式会社BuySell Technologies

Discussion