ESLint と Prettier の設定を共通化し、異なるプロジェクトでも同じ設定を使えるようにする(Shareable Configs 機能)

📆November 22, 2020🔖

🦥 複数プロジェクト間でコーディング規約を統一するの、マジでオススメです。

はじめに

この記事では、ESLint と Prettier の設定をプロジェクト間で共通化する方法について解説します。共通化するのに必要な知識(ESLint / Prettier で提供されている Sharable Configs 機能、npm パッケージへの公開、各プロジェクトでの読み込み方)をメインに解説していきます。

対象読者は、フロントエンドエンジニアとさせていただき、「ESLint / Prettier とは何か」と言った部分に関しては、この記事では割愛させていただきます。ご了承くださいませ。

背景と課題

僕たちの会社 J-CAT も創業して1年が過ぎ、だんだんとプロジェクトやコードベースの成果物も増えてきました。

プロジェクトが進んでいくにつれ、ここのコーディング規約はこうあるべきだよね、このデフォルトルールはいらないね、などとルールがどんどんアップデートされ、洗練されたものになっていきました。

しかし、一方で、最新のプロジェクトは社内の規約・ルールのアップデートに追従できているものの、古いプロジェクトでは古いルールが適用されたままになってしまうという問題が発生しました(まあそりゃそうだろって感じなのですが)。

古いプロジェクトを触る際に、最新のプロジェクトから設定ファイルを持ってきて手作業で反映を行う運用になってしまっていました。これだとさすがに運用が面倒で、あまりイケてないように感じていました。

そんな中、今月の Web Press がフロントエンド特集でたまたま買っていたので、読んだところ、Cybozu さんのフロントエンドのアーキテクチャが載っており、そこで ESLint の設定を共通化しているといことを知りました。インスピレーションを受け、僕たちも同じ構成にしてみようというのが背景です。

前置きが長くなりましたが、設定について解説していきたいと思います。

ESLint 設定の共通化

ESLint には Shareable Configs 機能というものがあり、これを使うことでプロジェクト間の設定を共通化することができます。設定ファイルを Shareable Config の設定を npm にパッケージを公開し、各プロジェクトでそれを読み込むという構成にしたいと思います。

Shareable Configs の画面スクリーンショット
Shareable Configs の画面スクリーンショット

GitHub でリポジトリを作ります。命名は、eslint-config-XXX とするのが良いと思います。npm init し、パッケージ名は、ESLint のドキュメントに書いてある通り eslint-config-XXX もしくは @XXX/eslint-config とします(僕たちは後者を選択しました。)

// eslint-config/package.json

"name": "@j-cat/eslint-config",

このパッケージに、ESLint の設定を書いていき、npm に公開します。

index.js

次に、index.js を作成し、共通化したい設定を書いていきます。rules 部分には、自分たちのプロジェクトで共通で使いたい設定を記述していきます。例として、僕たちのプロジェクトの一部を載せておきます。たとえば、no-console を warning にしたり、自前 CMS からの加工で v-html を使う機会が多いので ignore したりしています。

// eslint-config/index.js

module.exports = {
  parserOptions: {
    ecmaVersion: 2019,
    sourceType: "module",
  },
  env: {
    browser: true,
    es6: true,
    commonjs: true,
  },
  extends: ["prettier", "prettier/vue", "plugin:prettier/recommended"],
  plugins: ["prettier"],
  rules: {
    // 0 = off, 1 = warn, 2 = error
    "no-console": 1,
    "dot-notation": 0,
    "vue/no-v-html": 0,
  },
};

ここまでで基本的な設定は完了です。npm に公開していきましょう(npm のアカウント作成や CLI でのログインに関してはこの記事では割愛します)package.json に以下を追加し、public プロジェクトにします。

// eslint-config/package.json

"publishConfig": {
  "access": "public"
}

npm publish コマンドで npm に公開します。無事公開されたら完了です。

(おまけ)GitHub Actions で自動化

毎回 npm publish コマンドで公開しても良いのですが、面倒なので GitHub Actions で push をフックに公開されるようにします。npm からアクセストークンを取得し、GitHub リポジトリで設定します。

以下は GitHub Actions の例です。これで、master ブランチへの push をフックして GitHub リポジトリに公開することができます。

// eslint-config/.github/workflows/release.yml

name: Release on npm

on:
  push:
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: "12.x"
          registry-url: "https://registry.npmjs.org"
      - run: npm install
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

最終的なパッケージ構成は以下のようになります。

eslint-config のパッケージ構成
eslint-config のパッケージ構成

プロジェクトで使用する

各プロジェクトで、公開したパッケージを使用するように設定していきます。今回は、上記の通り @j-cat/eslint-config という命名でパッケージを作成したので、yarn add @j-cat/eslint-config -D コマンドで、インストールします。

プロジェクト内の .eslintrc ファイルで、extend します。今回の例では割愛していますが、他のルールセットも extends しています。@j-cat/eslint-config には Prettier の設定が含まれているので、extends の配列末尾に追加しています。(ここは正直あまり深くまでは理解できてないです)

(参考)https://dackdive.hateblo.jp/entry/2019/03/15/100000

// .eslintrc
module.exports = {
  extends: ['XXX', 'YYY', '@j-cat/eslint-config'],
};

これで eslint の設定を共通化することができました。次に、Prettier の設定の共通化について解説していきます。

Prettier 設定の共通化

ESLint と比べると設定手順が少なく簡単です。Prettier にも、ESLint と同じように Sharing configurations 機能があるので、こちらを利用して設定の共通化を行います。

Prettier の Sharing Configurations 機能ページ
Prettier の Sharing Configurations 機能ページ

同様に GitHub でリポジトリを作ります。命名は、prettier-config-XXX とするのが良いと思います。npm init し、パッケージ名は、ESLint のドキュメントに書いてある通り eslint-config-XXX もしくは @XXX/eslint-config とします(僕たちは後者を選択しました。)

パッケージ構成は以下のように非常にシンプルな形です。

index.json にはフォーマットのルールを json 形式で書いていきます。(json 以外の書き方もあるのでお好みで)以下は僕たちのプロジェクトの設定の一部を抜粋したものです。

// index.json 
{
  "arrowParens": "always",
  "trailingComma": "all",
  "singleQuote": true,
  "printWidth": 200
}

package.json は以下のようになります。main に先ほど設定した json ファイルを指定するようにします。他は特に目新しい設定はありません。

// package.json
{
  "name": "@j-cat/prettier-config",
  "version": "0.1.1",
  "main": "index.json",
  "author": "35d",
  "publishConfig": {
    "access": "public"
  }
}

設定が完了したら npm publish します。僕たちは ESLint の章で述べたのと同様に、GitHub Actions 等を用いて自動化しています。自動化の方法に関しては、上述の方法と全く同じなので本章では割愛します。

プロジェクトで使用する

使用したいプロジェクトで yarn add @j-cat/prettier-config -D でインストールします。

あとは、npm に publish された設定ファイルをプロジェクトに読み込ませるだけです。こちらも非常に簡単で、読み込ませたいプロジェクトの package.json に以下のように1行追加するのみです。

// 共通設定を使用するパッケージの package.json

"prettier": "@j-cat/prettier-config"

これにて Prettier 設定の共通化は完了です。(本当に超簡単)


以上で、ESLint と Prettier の設定共有方法です。最初にも述べましたが、複数プロジェクトを管理している企業等では、コーディング規約を統一するの本当にオススメです。

参考になった記事

  • Configuration File | Prettier
  • Shareable Configs | ESLint
  • 兎にも角にも公式ドキュメント。そもそもこういう機能があることすら知らなかったので、ためになった。

  • https://dackdive.hateblo.jp/entry/2019/03/15/100000
  • 完全に咀嚼しきれてないけど、ESLint と Prettier を併用するときの設定を解説してくれている