課題
eslint-config-aibnbを利用している場合に、テストコードなど、devDependenciesをimport(require)するコードが怒られる。
error 'ava' should be listed in the project's dependencies, not devDependencies import/no-extraneous-dependencies
原因
eslint-config-airbnbに含まれているeslint-plugin-importのno-extraneous-dependenciesというルールが、eslint-config-airbnb-baseの中で下記のように設定されているのが原因。(eslint-config-airbnbのバージョンが、11.2.0の場合。)
'import/no-extraneous-dependencies': ['error', {
devDependencies: false, // devDependenciesのimportを禁止
optionalDependencies: false,
}]
これはちょっと厳しすぎるので、テストコードなど一部のファイルだけでdevDependenciesのimportを許可したい。
対応策
eslint-config-airbnbのバージョンによって依存しているeslint-plugin-import、eslint-config-airbnb-baseのバージョンが違うので、対応が異なる。
eslint-config-airbnbの11.1.0以前
eslint-plugin-importのバージョンが、v1.14.0以前の場合。
コメントで一時的に無効にする
少なければこの方法で良さそう。コメントで向こうにする場合、他のルールまでもみ消さないように、どのルールを無効にするか明記した方がよい。(eslint-plugin-eslint-commentsを使うとそのあたりも制限できてよい)
import test from 'ava'; // eslint-disable-line import/no-extraneous-dependencies
// eslint-disable-next-line import/no-extraneous-dependencies
import test from 'ava';
test/.eslintrc.jsonを置く
テストコードをtest/
以下などソースコードと隔離されたディレクトリに置いている場合は、test/.eslintrc.json
(拡張子はお好きなやつを使う)を置いて、プロジェクトルートにある.eslintrc.json
のルールを上書きする。
module.exports = {
rules: {
...
'import/no-extraneous-dependencies': ['error', {
devDependencies: true, // devDependenciesのimportを許可
optionalDependencies: false,
}]
...
};
eslint-config-airbnbの11.2.0
devDependenciesの読み込みを許可するパスをルールに書く
eslint-plugin-importのv1.14.0からno-extraneous-dependenciesにbool値だけでなく、devDependenciesの読み込みを許可するファイルパスを配列で渡すことができるようになったので、それを使う。
'import/no-extraneous-dependencies': ['error', {
devDependencies: ['**/*.spec.js'], // *.spec.jsのdevDependenciesのimportを許可
optionalDependencies: false,
}]
eslint-config-airbnbの12.0.0以降
eslint-config-airbnb-baseのv8.0.0以降では、下記のように、testディレクトリ以下ではdevDependenciesの読み込みを許可するようになっている。(この部分)
// Forbid the use of extraneous packages
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md
// paths are treated both as absolute paths, and relative to process.cwd()
'import/no-extraneous-dependencies': ['error', {
devDependencies: ['spec/**', 'test/**', 'tests/**', '**/__tests__/**'],
optionalDependencies: false,
}],
なので、上記以外のパスの場合は自分でルールを上書きしてあげる必要がある
'import/no-extraneous-dependencies': ['error', {
devDependencies: ['**/*.spec.js'],
peerDependencies: false
}]
おわり
eslint-config-airbnbってあまりアップデートしないけど、今回のno-extraneous-dependenciesのように改善されているルールもあるので、古くなっていたら最新にしましょう!!!
おまけ
eslint-config-airbnb-baseのmasterの内容を見ると、no-extraneous-dependenciesのdevDependenciesに下記のファイルパスの指定が追加されており、だいたいのパターンはカバーされていそう。(この部分)
// Forbid the use of extraneous packages
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md
// paths are treated both as absolute paths, and relative to process.cwd()
'import/no-extraneous-dependencies': ['error', {
devDependencies: [
'test/**', // tape, common npm pattern
'tests/**', // also common npm pattern
'spec/**', // mocha, rspec-like pattern
'**/__tests__/**', // jest pattern
'test.js', // repos with a single test file
'test-*.js', // repos with multiple top-level test files
'**/*.test.js', // tests where the extension denotes that it is a test
'**/webpack.config.js', // webpack config
'**/webpack.config.*.js', // webpack config
'**/rollup.config.js', // rollup config
'**/gulpfile.js', // gulp config
'**/Gruntfile', // grunt config
],
optionalDependencies: false,
}],
これがpublishされれば、本記事で設定した内容は不要になりそうなので、早くpublishしてほしい。