今回は、静的解析ツールのESLintとコードフォーマッターのPrettierをNode.js & TypeScriptプロジェクトに導入する手順を整理していきたいと思います。実際の現場でも使っているケースがかなり多いですが、私自身何となくで使っていたため、正しい理解をできていませんでした。そのため、今回は整理しながら各パッケージの役割や各ルールについての理解を深めていければと思っています。
ESLintについて
ESLintとは
ESLintは、JavaScriptやTypeScriptのコード品質やスタイルを自動的にチェックし、一貫性を保つための静的解析ツールです。コードの静的解析を行い、構文エラーや潜在的なバグを検出し、プロジェクト固有のコーディングスタイルに従った指針を強制します。特に、チーム開発時には、コード品質の統一性を維持し、エラーやバグを事前に捉えるため、開発プロセスを改善することが可能。
ESLintの特徴
- 静的解析とリントルール:ESLintはコードを解析し、カスタマイズ可能なリントルールを適用してエラーや潜在的な問題を検出する。これにより、コード品質が向上し、バグを事前に発見可能。
- カスタマイズ性:プロジェクトに合わせてリントルールを設定可能。開発チームが独自のコーディングガイドラインに従うことができ、一貫性が保たれる。
- 自動修正:ESLintは一部の問題を自動的に修正可能。コードのフォーマットやスタイルを自動的に統一することで、コードレビューの手間を軽減する。エディターと結合させることにより、さらに効率化可能。
- 豊富なプラグイン:ESLintは多くのプラグインと拡張機能をサポートしており、異なるプロジェクトやフレームワークに適用可能。これにより、様々なコーディング要件に対応できる。
- 開発効率向上:コードの品質を向上させ、バグを事前に検出することで、開発効率が向上する。一貫性のあるコーディングスタイルはコラボレーションを容易にし、保守性を高める。
Prettierについて
Prettierとは
Prettierは、コードのフォーマットやスタイルを自動的に整えるコードフォーマッターツールです。開発者がコードのスタイルガイドに従う手間を省き、一貫性のあるコードを生成する。設定が簡単で、JavaScriptやTypeScriptをはじめとする多くのプログラミング言語に対応している。Prettierはコードのインデント、セミコロンの挿入、改行の扱いなどを統一し、コードの可読性を向上させてくれます。多くのエディタやIDEと統合でき、コードを保存時に自動的に整形が可能。プロジェクト全体で一貫性のあるコーディングスタイルを維持し、コードレビューの手間を減らすのに役立ちます。
Prettierの特徴
- 自動コードフォーマット:Prettierはコードの自動フォーマットを提供し、コーディングスタイルを自動的に整える。手動でのフォーマット作業を不要にし、一貫性のあるコードを維持する。
- 簡単なカスタマイズ:カスタム設定を提供し、プロジェクトの要件に合わせてコーディングスタイルを調整できる。設定ファイルを作成し、プロジェクト全体で一貫性を保つ。
- 連携と効率化:エディタと連携し、保存時に自動フォーマットを実行可能。これにより、コードレビューの手間が減少し、開発プロセスがスムーズとなる。
ESLintとPrettierの違いとそれぞれの役割
ESLintはコード品質とルール遵守に焦点を当て、Prettierはコードの整形と一貫性の向上に焦点を当てている点が違い。一般的に、両方を組み合わせて使用することで、コードの品質とスタイルの両方を管理することができるため、併用することが多い。
特徴 | ESLint | Prettier |
主な役割 | コード品質の向上、バグの検出 | コードフォーマット、スタイルの一貫性 |
機能 | エラーチェック、問題の検出、ルール遵守 | 自動コード整形、スタイルの自動適用 |
カスタマイズ性 | プロジェクト固有のリントルールの設定可 | 基本的なスタイルオプションの設定可 |
カスタムルール設定 | サポートあり | サポートなし |
フォーマットのカスタマイズ | 一部カスタマイズ可能 | カスタムルールより限定的 |
対応言語 | JavaScriptなど多くの言語に対応 | JavaScript、HTML、CSSなど多くの言語に対応 |
自動修正機能 | 一部のエラーと警告を修正できる | コード全体の自動整形 |
役割の比較 | コード品質向上、ルール遵守強調 | コードスタイルの一貫性向上が主な焦点 |
導入の流れ
前回の記事を参考にNode.js + TypeScriptの実行環境を構築
開発環境
- node:
v18.15.0
- npm:
v9.5.0
- typescript:
v5.0.2
- eslint:
v8.48.0
- prettier:
v3.0.3
- OS:
MacOS Monterey
導入手順
実行環境の構築
まずはNode.js + TypeScriptで実行できる環境を構築。
構築方法は以下をベースに実施しましたので、まだ構築できていない方は参考にしてください。
ESLint編:必要なパッケージのインストール
$ npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
eslint
: コード品質と規約のチェックを行う静的解析ツール@typescript-eslint/parser
: TypeScriptコードのESLint解析を可能にするパーサー@typescript-eslint/eslint-plugin
: TypeScript向けESLintルールを提供するプラグイン
ESLint編:設定ファイルの作成とルールの定義
.eslintrc.jsの作成
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
env: {
browser: true,
commonjs: true,
},
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.eslint.json',
tsconfigRootDir: __dirname,
},
ignorePatterns: ['dist'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
rules: {
eqeqeq: 'error', //===にしないとエラー
'no-console': 'warn', //console.xxxを使うと警告
'no-warning-comments': [
//対象のコメントを書くと警告
'warn',
{ terms: ['todo', 'fixme', 'memo'], location: 'anywhere' },
],
'max-statements': ['warn', 30], //宣言した関数や変数の上限値
'max-lines': ['warn', 500], //1ファイルの最大行数
'max-lines-per-function': ['warn', { max: 30, skipBlankLines: true }], //関数内の行数が30行超えると警告
'max-depth': ['warn', 3], //ネストが3を超えると警告
complexity: ['warn', 5], //複雑度が5を超えると警告
'@typescript-eslint/quotes': ['error', 'single'],
'@typescript-eslint/naming-convention': [
'warn',
{ selector: 'variableLike', format: ['camelCase'] },
{ selector: 'method', format: ['camelCase'] },
{ selector: 'typeLike', format: ['PascalCase'] },
{ selector: 'parameter', format: ['camelCase'] },
],
'@typescript-eslint/no-explicit-any': ['error'],
'@typescript-eslint/no-unused-vars': ['error'],
'@typescript-eslint/no-require-imports': ['error'],
},
};
tsconfig.eslint.jsonの作成
.eslintrc.js
ファイル自体にもESLintの対象に含めるため、tsconfig.json
を継承する形でtsconfig.eslint.json
ファイルを作成します。
{
"extends": "./tsconfig.json",
"compilerOptions": {
"allowJs": true
},
"include": ["src", ".*.js", "*.js"]
}
参考:サバイバルTypeScript:TypeScript ESLintの設定ファイルを作る
Prettier編:必要なパッケージのインストール
$ npm install -D prettier eslint-config-prettier
Prettier編:設定ファイルの作成とルールの定義
.prettierrc.jsの作成
ルート直下に.prettierrc.js
ファイルを作成する。
今回は.eslintrc.jsに併せてJSファイルで作成したが、ファイル名に関しては、.prettierrc
や.prettierrc.json
でも問題ない。
https://prettier.io/docs/en/configuration
ルールの定義
module.exports = {
tabWidth: 2,
printWidth: 100,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'all',
bracketSpacing: true,
arrowParens: 'always',
};
あえて記載しているルールもあるが、基本的にはデフォルトで十分である。あとはプロジェクトやチームの慣習に併せてルールを設定する。
各ルールの詳しい説明はこちら → リンク
.eslintrc.jsに追加
eslint-config-prettierを適用させるために以下の行を追加
module.exports = {
root: true,
...
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'prettier', //------------ 追加
],
rules: {...},
};
VSCodeの拡張機能追加
正直これらの拡張機能を使わないとあまり恩恵を受けれないため必ず導入する。
ESLint
Prettier
settings.json
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": ["source.fixAll.eslint"],
"editor.formatOnSave": true,
}
プロジェクトのみに上記ルールを適用したい場合は、ルート直下に.vscode/settings.json
を作成し、上記ルールを記載する。そうすると、VSCode全体で定義しているルールを上書きしてくれる。
設定ファイルと各ルールの説明
ESLint
プロパティ
プロパティ | 説明 | 役割 |
root | 設定ファイルのルートディレクトリを示すブール値。 | ESLintの設定ファイルがプロジェクトのルートにあることを指定。 |
parser | 使用するパーサーの指定。通常、プログラミング言語のバージョンや拡張機能に対応したパーサーを指定。 | TypeScriptファイルを解析するために@typescript-eslint/parserを指定。 |
plugins | ESLintに追加のプラグインを提供する。 | TypeScriptファイル用の@typescript-eslintプラグインを追加。 |
env | コードが実行される環境を定義するオブジェクト。 | ブラウザとCommonJS環境などをサポートする設定。 |
ignorePatterns | 特定のファイルやディレクトリを無視するための正規表現の配列。 | distディレクトリを無視してESLintが検証しないようにする。 |
extends | 他のESLint設定ファイルを拡張するための配列。 | TypeScript用の推奨設定を拡張。 |
rules | ルールの設定オブジェクト。各ルールに対して設定を指定し、コードの品質とスタイルをカスタマイズ。 | 例: eqeqeqルールを設定して===を強制する。 |
parserOptions | パーサーのオプションを指定するオブジェクト。パーサーのバージョンやプロジェクトの設定を含む。 | TypeScriptファイルを解析するためのオプションを指定。 |
ルールの書き方
重要度 | 説明 |
off or 0 | ルールを無効にする。 |
warn or 1 | ルールを警告として有効にする。ルール違反は警告として報告されるが、 プログラムの終了コードに影響しない。 |
error or 2 | ルールをエラーとして有効にする。ルール違反はエラーとして報告され、 プログラムの終了コードが1に設定される。 |
rules: {
eqeqeq: 'error', // or 2
'no-console': 'warn', // or 1
'no-warning-comments': 'off' // or 0
}
ルールの無効化
参考:https://eslint.org/docs/latest/use/configure/rules#disabling-inline-comments
■ ファイル全体への適用
/* eslint max-lines: 0, no-console: 0 */
console.log('ログ出力:1行目') //警告が無効化
...
...
console.log('ログ出力:1000行目') //500行超えていても警告が無効化
■ 一定範囲への適用
const test = () => {
/* eslint-disable */
if ('条件1') {
if ('条件2') {
if ('条件3') {
if ('条件4') {
return true
} else {
return false
}
}
}
}
/* eslint-enable */
};
※ complexity
やmax-depth
を無効化する例
■ 対象行のみの適用
記載方法は2パターン
- 無効対象行の前の行
- 無効対象行と同じ行
// eslint-disable-next-line
const anyObject: any = { title: 'text' };
const unused = 1; // eslint-disable-line no-unused-vars
Prettier
ルール
ルール名 | 説明 | デフォルト |
printWidth | 1行の文字数の制限を指定。 | 80 |
tabWidth | インデントに使用されるスペースの数を指定。 | 2 |
useTabs | インデントにタブを使用するかどうかを指定。 | FALSE |
semi | 文末にセミコロンを自動的に追加するかを指定。 | TRUE |
singleQuote | シングルクォート(シングル引用符)を使用するかどうかを指定。 | FALSE |
quoteProps | オブジェクトのプロパティ名のクォートスタイルを指定。 | as-needed |
jsxSingleQuote | JSX属性内のシングルクォートを使用するかどうかを指定。 | FALSE |
trailingComma | オブジェクトリテラルの末尾にカンマを追加するかを指定。 | all |
bracketSpacing | オブジェクトリテラルの中括弧の前後にスペースを追加するかを指定。 | TRUE |
bracketSameLine | 配列の中括弧を同じ行に配置するかどうかを指定。 | FALSE |
arrowParens | アロー関数の引数に括弧を付けるかどうかを指定。 | always |
rangeStart | フォーマット対象の範囲指定の開始位置を指定。 | 0 |
rangeEnd | フォーマット対象の範囲指定の終了位置を指定。 | Infinity |
parser | 使用するパーサーを指定。 | None |
filepath | 出力のファイルパスを指定。 | None |
requirePragma | ファイルにプラグマコメント(// @prettier)が必要かどうかを指定。 | FALSE |
insertPragma | ファイルの先頭にプラグマコメントを挿入するかどうかを指定。 | FALSE |
proseWrap | テキストの折り返し方法を指定。 | preserve |
htmlWhitespaceSensitivity | HTMLの空白文字の扱いを指定。 | css |
vueIndentScriptAndStyle | Vueファイル内のスクリプトとスタイルのインデントを指定。 | FALSE |
endOfLine | 行末文字を指定(LF、CRLF、CRのいずれか)。 | LF |
embeddedLanguageFormatting | 埋め込まれた言語のフォーマット設定。 | auto |
singleAttributePerLine | JSX要素内の属性を1行に1つずつ表示するかどうかを指定。 | FALSE |
ルールの無効化
// prettier-ignore
とコメント追加すると、次行に対しては無効化が可能
// prettier-ignore
まとめ
今回は、静的解析ツールのESLintとコードフォーマッターのPrettierをNode.js & TypeScriptプロジェクトに導入する手順をまとめてみました。改めて各プロパティやルールがどのような役割をしているのか理解することができました。
これらのツールが導入されていないと、不要なPRレビューが発生したり、フォーマッターの自動修正により余計な差分が発生するケースも多々あります。そのために、チームやプロジェクト間でルールを決めて開発効率をさらに良くする動きが取れるといいですね。
ここまでご覧いただきありがとうございました。