0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.jsでcommit時にaddされているファイルにのみESLintとPrettierを実行する

Last updated at Posted at 2021-12-04

何をするのか

タイトル通りで、Next.jsでcommit時にステージング(git add)されているファイルにのみnext lint --fixprettier --writeを実行します。
ググれば日本語の記事でもやり方は沢山出てくるのですが、意外と落とし穴があったので今回はその詳細を書いていこうと思います。

※大前提として初めからeslintが導入されている11以降のバージョンを使用しましょう。

よくあるやり方

huskylint-stagedを入れて.husky/_/pre-commitpackage.jsonで以下のように設定して、commitする。

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint-staged
{
 "scripts": {
   "dev": "next dev",
   "build": "next build",
   "start": "next start",
   "lint": "next lint --dir src",
   "lint:fix": "next lint --fix --dir src",
   "format": "prettier --write ./src/**/*",
   "prepare": "husky install"
 },
 "dependencies": {
 }
 "devDependencies": {
 },
 "lint-staged": {
   "*.(js|ts)?(x)": [
     "yarn format",
     "yarn lint:fix"
   ]
 }
}

これの何が問題かというと、これだと該当する全てのファイルにリントとフォーマットが効いてしまいます。

今回はステージングされているファイルにのみ反映したいのです。
lint-stagedという名前ですが、そこら辺をよしなにやってくれたりはしないようです。

やり方

「よくあるやり方」の問題点ですが、.lintstagedrc.jsを使ってコマンドを動的に生成する事で解決します。

ただその前にそこまでの一通りの手順を記載いたします。
また今回はJavaScript Standard Styleを適用したいと思います。(ここはお好みで何でも良いです)

パッケージの導入

※全部一気にやってもいいですが、今回はわかりやすく分けてインストールしています。

まずNext.jsのプロジェクトが作成し終わったら、そのディレクトリで、

yarn add --dev eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node

を実行して、JavaScript Standard Styleに必要なパッケージをインストールします。

次にコードフォーマッターのprettierと、eslintprettierのルールの競合を回避してくれるeslint-config-prettierをインストールします。

yarn add --dev prettier eslint-config-prettier

そして最後にcommitpushの前に特定の処理を挟んでくれるhuskyと、ステージングされているファイルの処理を行うためのlint-stagedをインストールします。

yarn add --dev husky lint-staged

パッケージの設定

次にeslinthuskyの設定を行います。

まずeslintrc.jsonを以下のように編集します。

{
  "extends": ["next/core-web-vitals", "standard", "prettier"]
}

このstandardprettierはそれぞれJavaScript Standard Styleeslint-config-prettierの設定です。
またこの時の注意点ですがフォーマッターのルールはnextより後に書きます。

次にhuskyの設定を行います。
以下のコマンドを実行してhuskyを初期化します。

npx husky-init && yarn

↑が実行されると、自動でルートディレクトリに.husky/_/pre-commitが作成されるので、そのファイルを以下のように書き換えます。

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint-staged

最後にlint-stagedの設定を行います。
ルートディレクトリに.lintstagedrc.jsを作成して、以下の内容を書き込みます。

module.exports = {
  '*.(js|ts)?(x)': filenames => {
    const rawFilePaths = filenames.map(file => {
      const cwd = process.cwd()
      const isMatchingPathFormat = file.includes(process.cwd())
      const correctCwd = isMatchingPathFormat ? cwd : cwd.replace(/\\/g, '/')
      const rawFilePath = file.replace(correctCwd, '.')
      return rawFilePath
    })

    return [
      `prettier --write ${rawFilePaths.join(' ')}`,
      `next lint --fix --file ${rawFilePaths.join(' --file ')}`
    ]
  }
}

以上でインストール&設定は完了です。
これでgit commitすると、自動でステージングされているファイルにリントとフォーマットが効くようになりました。

.lintstagedrc.jsについて

まず.lintstagedrc.jsが何をやっているのかですが、returnで返される配列のコマンドをcommitの前に実行してくれます。
つまり単純に

module.exports = {
  '*.(js|ts)?(x)': filenames => [
    'yarn format',
    'yarn lint:fix'
  ]
}

のように書くと、ステージングされたファイルにjs/jsx/ts/tsxが存在すると、yarn formatyarn lintが実行されます。

ただしこれでは「よくあるやり方」で書いたように全てのファイルにリントとフォーマットが反映されてしまいます。
そのためステージングされているファイルにのみ反映するコマンドを引数filenamesを使用して生成する必要があります。

コード解説

このfilenamesですが、こいつはステージングされているファイルの絶対パスを列挙した配列であり、中身は以下のようになっています。

[
  'C:/Users/username/Desktop/my_project/.lintstagedrc.js',
  'C:/Users/username/Desktop/my_project/next.config.js',
  'C:/Users/username/Desktop/my_project/src/pages/members/index.tsx'
]

この配列をprocess.cwd(ここではC:/Users/username/Desktop/my_projectが出力される)を使ってプロジェクトルートまでを.に置換します。

const rawFilePaths = filenames.map(file => {
  const cwd = process.cwd()
  const isMatchingPathFormat = file.includes(process.cwd())
  const correctCwd = isMatchingPathFormat ? cwd : cwd.replace(/\\/g, '/')
  const rawFilePath = file.replace(correctCwd, '.')
  return rawFilePath
})
[
  './.lintstagedrc.js',
  './next.config.js',
  './src/pages/members/index.tsx'
]

あとはこの配列を使ってお好みのコマンドが生成できます。
例えば上記のprettier --write ${rawFilePaths.join(' ')}であれば、prettier --write ./.lintstagedrc.js ./next.config.js ./src/pages/members/index.tsxとなります。

注意点

isMatchingPathFormatcorrectCwdですが、windowsの場合process.cwd()の出力がC:\Users\username\Desktop\my_projectのようにスラッシュがバックスラッシュになってしまう事があるのでそれの調整をしています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?