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 3 years have passed since last update.

【コピペだけで実装】Next.jsにPrettierとESLintを搭載したHuskyを導入する

Last updated at Posted at 2021-09-11

皆さんPrettierやESLintってどのタイミングで適用させてますか?

僕は今まで手動で行っていたのですが、だんだん面倒になり、そういえばHuskyとかいうパッケージでGitのコミット時にフォーマットを整えてくれるやつあったな〜

と思い、Huskyを導入しました。

Huskyはバージョンごとに扱いが少し異なるそうなので、中々手こずりました.

もう二度とHuskyで時間は食われたくないので、そんな意味も込めて、Huskyの導入方法を備忘録として書いていきます。

特に詳しい説明は致しませんので、気になる点がございましたらコメントにて質問していただくか、ご自身で調べてください。

また、Next.jsはTypeScriptを前提として設定を行いますのでご了承下さい。

それでは説明していきます!

パッケージのインストール

// npm
npm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint  eslint-config-prettier eslint-plugin-react husky@6 lint-staged eslint-plugin-import eslint-plugin-prettier eslint-plugin-react-hooks

// yarn
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint  eslint-config-prettier eslint-plugin-react husky@6 lint-staged eslint-plugin-import eslint-plugin-prettier eslint-plugin-react-hooks

huskyのバージョンは6でインストールして下さい。

package.json

以下の内容を追加

package.json
 "scripts": {
    "check-types": "tsc --noEmit",
    "lint": "eslint **/**.ts **/**.tsx",
    "lint:fix": "eslint **/**.ts **/**.tsx --fix",
    "format": "prettier --write **/**.ts **/**.tsx",
    "test-all": "npx yarn-run-all lint check-types lint:fix",
    "prepare": "npx husky install",
    "lint-staged": "lint-staged"
  },
  "lint-staged": {
    "*.@(css)": [
      "prettier --write --parser css"
    ],
    "*.@(ts|tsx)": [
      "yarn lint",
      "yarn format"
    ]
  },

tsconfig.json

以下をコピペ

tsconfig.json
{
  "compilerOptions": {
    "rootDir": "src", // srcディレクトリ配下に置いている場合はこれを追加
    "typeRoots": ["node_modules/@types"],
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "include": ["next-env.d.ts", "src"],
  "exclude": ["node_modules", ".next", ".out"]
}

tsconfig.eslint.json

tsconfig.eslint.json
{
  "extends": "./tsconfig.json",
  "include": ["next-env.d.ts", "src"],
  "exclude": ["node_modules", ".next", "out"]
}

.eslintrc.json

.eslintrc.json
{
  "root": true,
  "env": {
    "browser": true,
    "es6": true,
    "node": true
  },
  "extends": [
    "plugin:react/recommended",
    "plugin:import/errors",
    "plugin:import/warnings",
    "plugin:import/typescript",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2020,
    "project": "./tsconfig.eslint.json",
    "sourceType": "module"
  },
  "plugins": [
    "@typescript-eslint",
    "import",
    "react",
    "react-hooks",
    "prettier"
  ],
  "rules": {
    "react/react-in-jsx-scope": "off",
    "no-use-before-define": "off",
    "prefer-const": "warn",
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-use-before-define": [
      "error"
    ],
    "no-void": [
      "error",
      {
        "allowAsStatement": true
      }
    ],
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "vars": "all",
        "args": "after-used",
        "argsIgnorePattern": "_",
        "ignoreRestSiblings": false,
        "varsIgnorePattern": "_"
      }
    ],
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "js": "never",
        "jsx": "never",
        "ts": "never",
        "tsx": "never"
      }
    ],
    "react/jsx-filename-extension": [
      "error",
      {
        "extensions": [
          ".jsx",
          ".tsx"
        ]
      }
    ]
  },
  "overrides": [
    {
      "files": [
        "*.tsx"
      ],
      "rules": {
        "react/prop-types": "off"
      }
    }
  ],
  "settings": {
    "react": {
      "version": "detect"
    },
    "import/resolver": {
      "node": {
        "paths": [
          "src"
        ]
      }
    }
  }
}

.prettierrc

.prettierrc
{
  "printWidth": 140,
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all"
}

ご自身の好きなフォーマットに変えて下さい。

ここまで来たら、一旦、PrettierやESLintを走らせてみて下さい。

// prettier
npm run format
yarn format

// ESLint
npm run lint
yarn lint

// 型チェック
npm run check-types
yarn check-types

Huskyの設定

さて、これでPrettierとESLintの設定は完了です。

あとはHuskyにこれらのコマンドを走らせるだけです!

Huskyの初期化

// npm
npm run prepare

// yarn
yarn prepare

するとプロジェクト直下に.huskyディレクトリが作成されます。

そしたら以下のコマンドでファイルを作成。

特に理由がない限り、pre-commitを作成したほうが良いと思います。

// コミット時にHuskyを走らせたい場合(おすすめ)
touch .husky/pre-commit

// プッシュ時にHuskyを走らせたい場合
touch .husky/pre-push

pre-commitもしくはpre-pushに以下をコピペ

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

// npm
npm run lint-staged
git add .

// yarn
yarn lint-staged
git add .

ファイルの読み取り権限追加

// commitの場合
chmod a+x .husky/pre-commit

// pushの場合
chmod a+x .husky/pre-push

これでHuskyの設定は完了です!

実際にHuskyが走るかチェックしてみましょう!

git add .
git commit -m 'apply husky'
yarn run v1.22.11
$ lint-staged
✔ Preparing...
✔ Running tasks...
✔ Applying modifications...
✔ Cleaning up...
✨  Done in 11.36s.

git push

ESLintの設定に引っかかる場合はその箇所を直してからまたコミットして下さい。

また、プッシュ時に実装している方もやり方は同じです。

ただ、Huskyが走るタイミングがgit commitgit pushだけの違いです。

いかがだったでしょうか?

冒頭にも述べましたが、Huskyはバージョンによって扱い方が少し変わるようなので厄介ですね。

今回書いたこの記事が、自分的には一番しっくり来ました。

なので、皆さんがこの記事をコピペするだけで実装できることを祈ってます(笑)。

以上、「【コピペだけで実装】Next.jsにPrettierとESLintを搭載したHuskyを導入する」でした!

Thank you for reading

参考記事

この記事を書くにあたって、参考にさせていただいた記事となります。

husky v6 のインストール方法と使い方。lint-staged も導入して、品質を保とう
Next.js (TypeScript) に ESLint と Prettier を導入し、コードを綺麗に保とう

ご協力頂き誠にありがとうございます!

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?