6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年4月26日 りあクト! 第6章 ESLintの適用ルールをカスタマイズする (p.54~)

依存パッケージをリストアップする

npm info パッケージ名 peerDependenciesを実行すると、依存しているパッケージをリストアップできます。 以下の例では、styled-componentsの依存パッケージをリストアップしています。

➜  frontend git:(feature/add_#403) npm info styled-components peerDependencies

{
  react: '>= 16.8.0',
  'react-dom': '>= 16.8.0',
  'react-is': '>= 16.8.0'
}

.eslintrc.jsをカスタマイズ

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: [ // 
    'plugin:react/recommended', // ESLint の組み込みルールに対する公式推奨の共有設定 
    'airbnb', // 上のrecommendedと順番が前後すると意図しないところで TypeScript のコードに ESLint がエラーを指摘したりするようになる
    'airbnb/hooks',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/typescript',
    'plugin:@typescript-eslint/recommended',
    // eslint:recommended から TypeScript の一般的な文法とバッティングするルールを 調整するための共有設定
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: { // parserである@typescript-eslint/parser へ渡すオプションを定義します。
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    project: './tsconfig.eslint.json', // 別ファイルを用意することでパーサが npm パッケージのファイルまでパースしてしまって、VS Code と連携させた際のパフォーマンスを落としたり、新規ファイルのパースの失敗を防ぎます。
    sourceType: 'module',
    tsconfigRootDir: __dirname,
  },
  plugins: [
    '@typescript-eslint',
    'import',
    'jsx-a11y',
    'react',
    'react-hooks',
  ],
  root: true,
  rules: {
    // occur error in `import React from 'react'` with react-scripts 4.0.1
    'no-use-before-define': 'off',
    '@typescript-eslint/no-use-before-define': [
      'error',
    ],
    'lines-between-class-members': [
      'error',
      'always',
      {
        exceptAfterSingleLine: true,
      },
    ],
    'no-void': [
      'error',
      {
        allowAsStatement: true,
      },
    ],
    'padding-line-between-statements': [
      'error',
      {
        blankLine: 'always',
        prev: '*',
        next: 'return',
      },
    ],
    '@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'],
      },
    ],
    'react/jsx-props-no-spreading': [
      'error',
      {
        html: 'enforce',
        custom: 'enforce',
        explicitSpread: 'ignore',
      },
    ],
    'react/react-in-jsx-scope': 'off',
  },
  overrides: [
    {
      'files': ['*.tsx'],
      'rules': {
        'react/prop-types': 'off',
      },
    },
  ],
  settings: {
    'import/resolver': {
      node: {
        paths: ['src'],
      },
    },
  },
};
  • extendsに各プラグインルールの推奨の共有設定が記述してあります。
  • ESLintプラグインはインストールしただけでは読み込まれないため、extendsに設定することで使用可能になります。
  • 共有設定の順番には意味があります。共有設定間で設定ルールの値が衝突した場合、後に記述されたものが先に記述されたものを上書きする仕様になっています。
  • 依存関係の順番がある場合はドキュメントに書かれているはずなのでプラグイン・拡張ルールセットをインストールするときは、チェックしましょう。

parserのオプションで指定したtsconfig.eslint.json

別ファイルを用意することでパーサが npm パッケージのファイルまでパースしてしまうことによる、VSCodeと連携時のパフォーマンスの低下や、新規ファイルのパースの失敗を防ぎます。

extends内のprojectの記述で別ファイルを読み込む設定が行われています。

 parser: '@typescript-eslint/parser',
  parserOptions: { // parserである@typescript-eslint/parser へ渡すオプションを定義します。
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    project: './tsconfig.eslint.json', // 別ファイルを用意することでパーサが npm パッケージのファイルまでパースしてしまって、VS Code と連携させた際のパフォーマンスを落としたり、新規ファイルのパースの失敗を防ぎます。
    sourceType: 'module',
    tsconfigRootDir: __dirname,
  },

tsconfig.eslint.json

{
  "extends": "./tsconfig.json",
  "include": [
    "src/**/*.js",
    "src/**/*.jsx",
    "src/**/*.ts",
    "src/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

pluginsの設定

plugins: [
    '@typescript-eslint',
    'import',
    'jsx-a11y',
    'react',
    'react-hooks',
  ],
  root: true,
  • 読み込ませる追加ルールのプラグインです。
  • インストールしただけでは使えず、上記のように設定する事で使用可能になります。
  • rootオプションは、ESlintはデフォルトの挙動では親ディレクトリの設定ファイルまで読み込んでしまいます。trueにする事で防ぐことができます。(個々のケースで変更するべき)

VS Code拡張機能でコーディング中にESLintが走るように設定する

拡張機能 : ESLint

https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint

メニューの Code > Preferences > Settings で開いたタブグループ右横のアイコン『Open Settings (JSON)』から設定ファイル settings.json を開いて次の内容を追加

"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
},
"editor.formatOnSave": false,
"eslint.packageManager": "yarn",
"typescript.enablePromptUseWorkspaceTsdk": true
  • ファイル保存時にESLintの自動整形が走るようにする設定です。
  • 最後の行はプロジェクトがTypeScriptを仕様している場合、VSCodeの内蔵のLintを使用するか、プロジェクトのLintを使用するかの設定です。

.eslintignoreファイル

lintチェック対象外となるファイルを定義できるファイルです。

build/
public/
**/converage/
**/node_modules/
**/*.min.js
*.config.js
.*lintrc.js

package.jsonでnpmのスクリプトを追加

後半の三行を追加します。

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'",
    "preinstall": "typesync || :"
  },

typesyncとは

package.jsonを見て足りない型定義パッケージがあれば自動で追加してくれるパッケージです。

このプロジェクトではtypesyncがインストールされており、パッケージをインストールする際にpreinstallフックで自動的にtypesyncが走るように設定しています。

typesync || : スクリプト実行時にtypesyncがインストールされていない場合に何もしないようにすることでエラーを防いでいます。

ある種のスクリプト名は特別です。定義されている場合、preinstallスクリプトはパッケージがインストールされる前にyarnによって呼び出されます。互換性の理由から、install、postinstall、prepublish、prepareと呼ばれるスクリプトはすべて、パッケージのインストールが完了した後に呼び出されることになります。 スタートスクリプトの値のデフォルトは、node server.jsです。

  • yarn add {package} で任意のパッケージをインストール
  • yarn add コマンドの前に必ず実行される特別なスクリプト名のpreinstallにtypesyncを設定する事で、パッケージをインストールする事と同時に型定義ファイルもインストールできるようになります。
  • 初回のyarn installコマンド実行時にtypesyncはインストールされていない事で起こるエラーを防ぐために || : を付与しています。

参考

りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅱ. React基礎編】 p.54~

ESlint公式ドキュメント Rules