はじめに
どーも、入田 / ぐるたか
@guru_taka です!
本記事では
Next.js (TypeScript) を環境構築し、ESLint(読み方:イーエスリント)と Prettier(読み方:プリティア)を導入する方法を紹介します。
Next.js のバージョン 11 に対応しており、デフォルトで搭載されている ESLint の設定ファイルをベースとしています。
ESLint と Prettier を駆使することで、
コードが綺麗になるため、導入することを強くオススメしたいです。本記事では、VS Code 上で、ESLint で構文解析しながら、ファイル保存時に ESLint + Prettier によるコード整形する方法をハンズオン形式でまとめています。
ESLint と Prettier を含む Next.js (TypeScript) の環境構築の参考になれば幸いです!
バージョン情報
- node:15.11.0
- eslint: 7.30.0
- eslint-config-next: 11.0.1
- prettier: 2.3.2
- eslint-config-prettier: 8.3.0
- next: 11.0.1
- typescript:4.3.5
- react: 17.0.2
- react-dom: 17.0.2
ESLint とは?
ESLint とは、
JavaScript のコードが正しいかどうか、検証するためのツールです。コードの問題を発見したり、記述方法を統一できるようになり、
コードの品質を保つことができます。
Prettier とは?
Prettier とは、コードを綺麗に整えるフォーマッターです。
ESLint もコードの整形はできますが、
カバーしきれない部分を Prettier は補ってくれます。そのため、基本的には ESLint と Prettier を併用することが多いです。
ESLint と Preitter を Next.js (TypeScript) に導入する方法
- Next.js (TypeScript) の新規プロジェクトを作成
- Prettier のセットアップ
- ファイル保存で自動フォーマットする VS Code の設定
1. Next.js (TypeScript) の新規プロジェクトを作成
まず、Next.js (TypeScript) の新規プロジェクトを以下コマンドで作成しましょう。
# npm の場合
npx create-next-app next-ts-eslint-prettier --typescript
# yarn の場合
yarn create next-app next-ts-eslint-prettier --typescript
ディレクトリ構造は以下の通りです。
├── .eslintrc
├── .gitignore
├── README.md
├── next-env.d.ts
├── next.config.js
├── node_modules
├── package.json
├── pages
├── public
├── styles
├── tsconfig.json
└── yarn.lock
Next.js では、バージョン 11 から、ESLint がデフォルトで搭載されています。ESLint に関連するインストール済みのパッケージは以下 2 つです。
- eslint:構文解析のエンジン
- eslint-config-next:Next.js 専用の ESLint のルール
// package.json
{
...
"devDependencies": {
"eslint": "7.30.0",
"eslint-config-next": "11.0.1",
}
...
}
Next.js の新規プロジェクト作成時に生成された .eslintrc
は ESLint の設定ファイルを意味しており、デフォルトで eslint-config-next
の設定が適用されています(ルールの詳細は後述)
// .eslintrc
{
"extends": ["next", "next/core-web-vitals"]
}
現在 lint
コマンドを実行することで、構文解析ができますが、VS Code 上でリアルタイムに構文解析することもできます。方法は至ってシンプルで、VS Code で ESLint の拡張機能をインストールするだけです!(下図参照)
実際に、構文解析されるかどうか、確認してみましょう。ルートディレクトリに sample/index.tsx
というファイルを作成してください。コードは以下の通りです。
// sample/index.tsx
export default function index() {
return (
<div>
<img src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
<a href="/">test</a>
</div>
);
}
下図のように、ESLint によるエラーが表示されれば成功です!
エラー文の解説は、以下のようになります。
① Do not use img. Use Image from 'next/image' instead.
② Do not use the HTML a tag to navigate to /. Use Link from 'next/link' instead.
img
タグは next/image
の Image
、a
タグは next/link
の Link
を使用するようなエラーとなっています。
このように VS Code 上でリアルタイムに ESLint で構文解析できると、コードの保守性が高まります。
しかし、ファイル数が多いとき、全てのファイルを VS Code で確認するのは大変です。そのため、対象ファイルを一括で ESLint による構文解析したい場合は、lint
コマンドを使用します。
# npm の場合
npm run lint
# yarn の場合
yarn lint
上記のコマンドを実行してみると、VS Code 上ではエラーが出力されているにも関わらず、以下のように問題ない趣の結果が表示されます。
# 実行結果
$ next lint
info - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
✔ No ESLint warnings or errors
✨ Done in 1.50s.
対処法は複数ありますが、fwywd チームでは src
ディレクトリに pages
含むソースコードを管理。lint
コマンドのオプションで --dir src
とすることで、src
ディレクトリ配下にある指定ファイルが ESLint の対象となるようにしています。
実際に src
ディレクトリを作成し、以下 3 つのディレクトリを管理しましょう。
src
├── pages
│ ├── _app.tsx
│ ├── api
│ └── index.tsx
├── sample
│ └── index.tsx
└── styles
├── Home.module.css
└── globals.css
次に、package.json
の lint
コマンドに対し、--dir src
を記述してください。
// package.json
"scripts": {
...
"lint": "next lint --dir src"
...
},
lint
コマンドを実行し、VS Code 上のエラーと同様の結果が表示されれば成功です!
また、ESLint によるコード整形するコマンドは、以下のようになります。
// package.json
"scripts": {
...
"lint": "next lint --dir src",
// 追記
// src --ext .js,jsx,.ts,.ts: src ディレクトリ内の js, jsx, ts, tsx ファイルを対象
// --fix: コード整形
"lint:fix": "eslint src --ext .js,jsx,.ts,.tsx --fix"
...
},
実際に、ESLint でコード整形できるかどうか、動作確認します。.eslintrc
のように、設定ファイルを記述してみましょう。
// .eslintrc
{
"extends": ["next", "next/core-web-vitals"],
// 追記
"rules": {
// セミコロンない場合、エラー出力
"semi": ["error", "always"]
}
}
上記のように
ESLint で独自のルールを記述する場合は、rules
に記述します。詳細は
ESLint の公式ページをご覧ください。
すると、セミコロンがないファイル(例:
pages/index.tsx
)に対し、下図のようにエラーが出力されるようになります。
以下のコマンドを実行した後、自動でセミコロンが追加されれば成功です!
# npm の場合
npm run lint:fix
# yarn の場合
yarn lint:fix
このように ESLint のルールに従って、一括でコード整形できます(便利!)
今回 ESLint でルールを記述しましたが、以降 Prettier をメインにコード整形のルールを記述するため、先程のルールは削除して構いません。
// .eslintrc
{
"extends": ["next", "next/core-web-vitals"]
// 削除
// "rules": {
// // セミコロンない場合、エラー出力
// "semi": ["error", "always"]
// }
}
2. Prettier のセットアップ
次は Prettier のセットアップを行います。まず、Prettier の拡張機能をインストールしましょう。
Prettier におけるフォーマットの設定は VS Code 上でも設定できますが、チーム開発する場合、コード整形のルールにバラツキがあると、大変です。
そのため、コードベースで Prettier におけるコード整形のルールを記述します。主な方法は、以下 2 つです。
.prettierrc
ファイルを作成し、ルールを記述
package.json
にルールを記述
fwywd チームでは、省ファイルも意識して、package.json
に記述しており、以下のようなルールを設定しています。
// package.json
"prettier": {
"trailingComma": "all",// 末尾のカンマあり
"tabWidth": 2,// tab の長さは半角スペース 2 つ
"semi": true,// セミコロンあり
"singleQuote": true,// シングルクォーテーションに統一
"jsxSingleQuote": true,//jsx もシングルクォーテーションに統一
"printWidth": 100 // 1 行の最大文字数 100
},
ルールの詳細は公式の
Options · Prettier をご確認ください。上記の設定を記述することで、
VS Code 上の Prettier のルールではなく、上記のルールが適用されます。
続いて、以下 2 つのパッケージをインストールしましょう。
- prettier: 各ファイルをコマンドで、フォーマットできるようにするため
- eslint-config-prettier: ESLint と Prettier のコード整形がバッティングしないようするため
# npm の場合
npm install -D prettier eslint-config-prettier
# yarn の場合
yarn add -D prettier eslint-config-prettier
.eslintrc
に対し、以下のように記述することで、ESLint と Prettier のコード整形がバッティングしないようになります。(公式推奨)
// .eslintrc
{
// 追記:"prettier"
"extends": ["next", "next/core-web-vitals", "prettier"]
}
最後に、Prettier でフォーマットするコマンドを package.json
に記述しましょう。
// package.json
"scripts": {
...
"lint": "next lint --dir src",
"lint:fix": "eslint src --ext .js,jsx,.ts,.tsx --fix",
// 追記
// --write: フォーマット整形
// --ignore-path .gitignore: .gitignore に含まれているファイルはコード整形の対象外
// 対象ファイルの拡張子を指定
"format": "prettier --write --ignore-path .gitignore './**/*.{js,jsx,ts,tsx,json,css}'"
...
},
実際にルールに従って、フォーマットされるかどうか、確認してみましょう。src/sample/index.tsx
ファイルを以下のコードに差し替えてください。
// src/sample/index.tsx
export default function index() {
return (
<div className="sample">
test
</div>
)
}
format
コマンドを実行後、セミコロンが付き、ダブルクオーテーション -> シングルクォーテーションとなっていれば成功です!
# npm の場合
npm run format
# yarn の場合
yarn format
3. VS Code でファイル保存時に
ESLint と Prettier によるコード整形はできましたが、開発中に毎回コマンドを実行するのは、手間がかかります。そこで、ファイル保存時にコードの自動整形ができるように、VS Code の設定を行います。設定ファイル (.vscode/settings.json
) は以下の通りです。
// .vscode/settings.json
{
// デフォルトのフォーマッタを prettier に設定
"editor.defaultFormatter": "esbenp.prettier-vscode",
// ファイル保存時、prettier による自動フォーマット
"editor.formatOnSave": true,
// ファイル保存時、ESLint による自動フォーマット
"editor.codeActionsOnSave": {
"source.fixAll": true
}
}
ファイル保存時、自動でコードが整形されていれば成功です!
以上で、Next.js における ESLint と Prettier の基本的な設定は完了となります。
eslint-config-next の設定ファイル
/*
* @rushstack/eslint-patch is used to include plugins as dev
* dependencies instead of imposing them as peer dependencies
*
* https://www.npmjs.com/package/@rushstack/eslint-patch
*/
require('@rushstack/eslint-patch/modern-module-resolution');
module.exports = {
extends: [
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:@next/next/recommended',
],
plugins: ['import', 'react', 'jsx-a11y'],
rules: {
'import/no-anonymous-default-export': 'warn',
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
'jsx-a11y/alt-text': [
'warn',
{
elements: ['img'],
img: ['Image'],
},
],
},
...
};
以下の主要な ESLint のプラグインが搭載されています。
上記のプラグインに加え、
Next.js 独自の ESLint のプラグイン eslint-plugin-next
が搭載されています。ルールの詳細は
公式サイトをご覧ください。
Next.js において、
デフォルトの ESLint の設定ファイルは非常に完成度が高いです。基本的には
eslint-config-next
をベースに、ESLint のルールをカスタマイズすることをオススメします!
モジュールをインポートする順番を、アルファベット順になるよう設定
記述するルールは以下の通りです。
// .eslintrc
{
"extends": [
"next",
"next/core-web-vitals",
"prettier",
// 追記
"plugin:import/recommended",
"plugin:import/warnings"
],
"rules": {
// import の順番をルール化
// 参考:https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md
"import/order": [
"error",
{
"alphabetize": {
"order": "asc"
}
}
]
}
}
このように、モジュールをインポートする順番がファイル保存時に、アルファベット順になれば成功です。もし、うまくいかない場合は、VS Code を再起動して確かめてみてください!
最後に
以上になります。Next.js ver11 となってから、
デフォルトで完成度の高い ESLint の設定が施されており、より環境構築がしやすくなったと感じます。
これから Next.js (TypeScript) を環境構築しようとしている方、ESLint や Prettier の設定で悩まれている方の参考になれば幸いです!
スタイルファイルに対しても構文解析したい場合は、
Next.js に Stylelint を導入する方法 という記事にまとめていますので、是非チェックしてみてください!
ここまでご覧いただき、ありがとうございました!
株式会社キカガク コンテンツマーケティング責任者
入田 / ぐるたか
twitter:
@guru_taka