• 作成:

ESLintのコアのみのルールで相対importを禁止する

前提として絶対importを使っています

webpackの設定を以下のようにしています.

const path = require('path');

module.exports = {
  resolve: {
    extensions: ['*', '.js', '.jsx', '.json'],
    modules: [path.resolve('./src'), path.resolve('./node_modules')],
  },
};

こう設定するとアプリケーションの内部モジュールにも絶対importが使えるようになります.

これを導入した当時はあまりにもディレクトリが深く大量に存在して, 現在どこに居るか一々時間をかけて把握しないとimportが出来ないという問題が発生していたため, 苦肉の策として絶対importを導入することに決めました.

絶対importなら

import common from 'common';

とだけ書けば良いですが,

相対importだと自分がどの深さに居るか一々数えて

import common from '../../../common';

と書く必要があります. バカバカしいですよね.

しかしこれは諸刃の剣で, webpackを適切に通さないとbabel-nodeなどが使えなくなるという欠点があります.

その後ディレクトリのパスはちゃんと整理して, 深さを最大で2(src/foo/bar/hoge.jsx程度)まで抑えたので, もしかしたら絶対importは導入しなくても良かったかもしれません.

もしくはhomeを~で表現して~/commonのようにimportする方が明確で良かったかもしれません.

しかし, 今回は絶対importでやっていくことにしています. これが前提です.

相対importが混ざる

コードスタイルというのはどちらが美しいかというのも重要ですが, それ以上にプロジェクト全体で一貫性を持っているかが重要です.

今回の場合は絶対importと相対importが混ざってしまうのが気持ち悪いので統一したいです.

しかし他のメンバーに言っても人間同士のコミュニケーションなので, どうしてもスタイルのブレは混ざってしまいます. 所詮はコードスタイルの問題なので, 潔癖症じみた私以外気にしないで書いているというのも無視される原因です.

よって, こういう機械的ルールはESLintで防止したいです. ESLintでエラーにすることができれば, CIがエラーを出してくれるのでmergeを抑止することが出来ます.

ESLintのルール単体に相対import禁止ルールは存在しませんが, パターンで弾けました

ESLint自体やeslint-plugin-import に相対importを禁止するルールが無いか検索しました.

その単体のルールは存在しないようでした.

しかしissueに頭の良いコメントを見つけました.

Rule proposal: no-relative-path · Issue #669 · benmosher/eslint-plugin-import

no-restricted-importsにパターンが使えるので, これで抑止出来るというコメントです.

さっそく.eslintrcに適用して, 相対importを禁止することが出来ました.

{
  "rules": {
  "no-restricted-imports": ["error", { "patterns": ["./", "../"] }],
  }
}