Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9042

ESLint v7.0.0 の変更点まとめ

$
0
0

v6.8.0 | 次 (2020-05-22 JST)

ESLint 7.0.0がリリースされました。
多数の互換性のない変更、ルール追加、オプション追加、そしてバグ修正が含まれています。

以下は主要な変更点のまとめです。

ユーザー向けの変更:

プラグイン開発者向けの変更:

ツール開発者 (エディタ拡張等) 向けの変更:

質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。

🏢 日本語 Issue 管理リポジトリ
👫 日本語サポート チャット
🏢 本家リポジトリ
👫 本家サポート チャット


[PR] ESLint は開発リソースを確保するための寄付を募っています。
応援してくださると嬉しいです。

💥 互換性がない変更

Node.js 8.x/11.x のサポートを終了します

🔖 RFC044, #12700

Node.js 8.x は 2019-12-31 に、11.x は 2019-06-01 に寿命を迎えたため、ESLint もそれらのバージョンのサポートを停止しました。

ESLint 7.0.0 がサポートする Node.js のバージョンは ^10.12.0 || >=12.0.0となります。

動作を元に戻したい場合:

この変更は元に戻せません。
古い Node.js 環境をアップグレードするまで ESLint 7 を利用しないようにしてください。

overrides設定に一致するファイルを自動的にリント対象にします

🔖 RFC020, #12677

これまで、eslint libのようにディレクトリを指定したとき、ESLint はディレクトリ内の *.jsファイルをチェックしていました。Node.js が *.cjs/*.mjs拡張子を導入したり、TypeScript や Vue.js でも ESLint を使うようになったりしたので、この仕様は不便でした。

ESLint 7.0.0 からは *.jsに加えて overrides設定にマッチするファイルもチェックします。例えば、

.eslintrc.yml
overrides:-files:"*.js"extends:my-config-js-files:"*.ts"extends:my-config-ts

のような設定がある場合、eslint libコマンドは libディレクトリ内の *.tsファイルもチェックします。

なお、eslint lib/**のように Glob パターンを指定した場合は今まで通りに動作しますのでご注意ください。overrides設定にかかわらず Glob パターンにマッチする全てのファイルをチェックします。

プラグイン開発者へ:

あなたが管理するプラグインが *.js以外のファイルを対象にするルールを提供する場合、recommended設定に overridesを追加すると利用者は便利かもしれません。

動作を元に戻したい場合:

今まで通り overrides設定にかかわらず *.jsだけをチェックしたい場合は、コマンドに --ext jsを付与してください。--ext CLI オプションはこの新しい動作を上書きします。

--config CLI オプションによる設定ファイル内の相対パスの扱いが変わります

🔖 RFC037, #12887

ignorePatterns, overrides[].files, overrides[].excludedFiles設定に相対パスがあった場合、その相対パスは設定ファイルの場所を基準に解決されます (共有設定内のそれら相対パスは、利用元の.eslintrc.*ファイルの場所を基準に解決されます)。

ESLint 7 でも基本的には同様です。しかし、--config CLI オプションで読み込んだファイルのみ、それら相対パスは CWD を基準に解決されるようになります。これは CWD にある仮想的な .eslintrc.*ファイルから extendsされたのと同じ動作になります。

動作を元に戻したい場合:

この変更は元に戻せません。
もし、この変更が原因で意図しない挙動になった場合は、設定ファイル内の相対パスを書き換えてください。

--ignore-path CLI オプションによる無視ファイル内のパスの扱いが変わります

🔖 RFC037, #12887

.eslintignoreファイル内のパスは、そのファイルの場所を基準に解決されます。

ESLint 7 でも基本的には同様です。しかし、--ignore-path CLI オプションで読み込んだファイルのみ、それらパスは CWD を基準に解決されるようになります。

動作を元に戻したい場合:

この変更は元に戻せません。
もし、この変更が原因で意図しない挙動になった場合は、無視ファイル内のパスを書き換えてください。

プラグインの読込元ディレクトリが変わります

🔖 RFC047, #12922

ESLint 6 はすべての設定ファイルに書かれた plugins設定のプラグインを $CWD/node_modulesディレクトリから読み込みます。この動作のため、エディタ拡張等に適切な CWD を設定しなければプラグインを利用できず、Monorepo スタイルの開発などで不便でした。

ESLint 7 では、設定ファイルに書かれた plugins設定のプラグインは、各設定ファイルの場所を基準に読み込まれます。つまり、packages/alice/.eslintrc.ymlファイルに書かれたプラグインは packages/alice/node_modulesディレクトリから読み込まれます。

⚠️ 共有設定に書かれた plugins設定のプラグインは、それを extendsする利用元の .eslintrc.*ファイルの場所を基準に読み込まれます。そのため、共有設定からプラグインを利用する場合は引き続き peerDependenciesを利用する必要があります。

動作を元に戻したい場合:

以前と同様に $CWD/node_modulesディレクトリからすべてのプラグインを読み込みたい場合は --resolve-plugins-relative-to . CLI オプションを利用してください (末尾のドットに注意)。
--resolve-plugins-relative-to CLI オプションはこの新しい動作を上書きします。

デフォルトで無視するファイルが変わります

🔖 RFC051, #12888

ESLint 6 がデフォルトで無視するファイルは、以下のパターンにマッチするファイルでした。

  • .* (dotfiles)
  • /node_modules/** (CWD にある node_modulesディレクトリ内)
  • /bower_components/** (CWD にある bower_componentsディレクトリ内)

ESLint 7 では、以下のように変更されます。

  • .!(eslintrc.*) (.eslintrc.*設定ファイルを除く dotfiles)
  • /**/node_modules/** (node_modulesディレクトリ内)

動作を元に戻したい場合:

以前のように .eslintrc.*/bower_components/**を無視したい、またはサブディレクトリの node_modulesディレクトリを無視したくない場合、.eslintrc.*設定ファイルの ignorePatterns設定を利用してください。

.eslintrc.yml
ignorePatterns:-"!/*/**/node_modules/*"-".eslintrc.*"-"/bower_components/*"

ディレクティブコメントに説明を書けます

🔖 RFC033, #12699

ディレクティブコメントとは、/* eslint-disable */のような ESLint の動作変更を指示するためのコメントのことです。ルールを無効にする場合、その理由を明示しておくことは良いことです。しかし、ディレクティブコメントの理由を書くための標準的な方法はありませんでした。

ESLint 7 では、空白文字に囲まれた2つ以上のハイフン --を使ってディレクティブコメントに説明を追加できます。

/* eslint-disable a-rule -- このルールはバグっている */doSomething()/* eslint-disable another-rule
----------------
ここでは...(略
 */

動作を元に戻したい場合:

この変更は元に戻せません。
もし、既存のディレクティブコメントに--が含まれていて壊れてしまった場合は、その設定を設定ファイルの overrides等に移してください。

eslint:recommended設定が有効にするルールが増えます

🔖 #12920

新たに 3 つのルールが有効になります。

  • no-dupe-else-if ... if-else ifチェーンにおいて、前の if文の条件を満たすために絶対に真にならない if文を報告します。
  • no-import-assign ... import文で作成した変数への代入 (実行時エラーになる) を報告します。
  • no-setter-return ... セッター内にある値を返す returnを報告します。

動作を元に戻したい場合:

上記ルールを有効にしたくない場合は、設定ファイルに無効化する設定を追加してください。

extends:eslint:recommendedrules:no-dupe-else-if:"off"no-import-assign:"off"no-setter-return:"off"

複数のルールのチェックが厳しくなります

🔖 #12195, #12490, #12608, #12701, #12757, #12765, #12806, #12816, #12837, #12876, #12913, #12915, #12919, #12927

以下のルールはより多くのエラーを報告するようになりました。

  • accessor-pairs ... オブジェクト リテラルだけでなく、クラス メンバーもチェックするようになりました。
  • array-callback-return ... ES2019 で追加された flatMap()メソッドもチェックするようになりました。
  • computed-property-spacing ... オブジェクト リテラルだけでなく、クラス メンバーもチェックするようになりました。
  • func-names ... デフォルト エクスポートの関数宣言も名前が省略可能であるため、関数式と同じように名前の有無をチェックするようになりました。
  • no-constant-condition ... 埋込式がないか、全ての埋込式が定数であるテンプレートリテラルも定数であると認識するようになりました。
  • no-dupe-class-members ... 計算されたプロパティ名が定数だった場合は重複チェックをするようになりました。
  • no-extra-parens ... 代入演算子の左側についてもカッコの有無をチェックするようになりました。
  • no-implied-eval ... window.evalのようなグローバルオブジェクトのプロパティアクセスも認識するようになりました。
  • no-iterator ... 計算されたプロパティ名が定数だった場合も認識するようになりました。
  • [no-magic-number] ... BigInt リテラルも認識するようになりました。
  • no-proto ... 計算されたプロパティ名が定数だった場合も認識するようになりました。
  • no-restricted-modules ... 埋込式がないか、全ての埋込式が定数であるテンプレートリテラルも定数であると認識するようになりました。
  • quote-props ... プロパティ名としての BigInt リテラルも認識するようになりました。
  • radix ... parseInt()関数の第二引数が無効な数値 (2未満 or 36より大きい) の場合もエラーを報告するようになりました。
  • use-isnan ... case句の NaNもエラー報告するようになりました。
  • yoda ... BigInt リテラルとテンプレートリテラルも認識するようになりました。

他にもあるかも...

動作を元に戻したい場合:

この変更は元に戻せません。
もし、新しくエラーが報告された場合はコードを修正してください。

複数の Node.js/CommonJS 向けルールが廃止されます

🔖 #12898

Node.js/CommonJS 向けのルールが非推奨になりました。
代わりに eslint-plugin-nodeの対応するルールをご利用ください。

非推奨代わりのルール
callback-returnnode/callback-return
global-requirenode/global-require
handle-callback-errnode/handle-callback-err
no-mixed-requiresnode/no-mixed-requires
no-new-requirenode/no-new-require
no-path-concatnode/no-path-concat
no-process-envnode/no-process-env
no-process-exitnode/no-process-exit
no-restricted-modulesnode/no-restricted-require
no-syncnode/no-sync

動作を元に戻したい場合:

廃止されたルールは引き続き利用することができます。
ただし、廃止されたルールのコードは凍結され、今後はバグ修正や機能追加が行われません。早めの移行をお勧めします。

個人設定の利用がランタイム警告を出力します

🔖 RFC032, #12678

個人設定とは、OS のホームディレクトリ (例: /home/foo/, C:\Users\foo\) に配置された .eslintrc.*設定ファイルのことです。ESLint はプロジェクト内に設定ファイルが見つかると個人設定を (親ディレクトリであっても) 無視し、プロジェクト内に設定ファイルが見つからないと個人設定を (親ディレクトリでなくても) 利用します。

この個人設定の仕組みは ESLint 6.7.0 で非推奨になりました

ESLint 7 では、個人設定の仕組みを利用すると標準エラー出力に非推奨警告を出力するようになります。

動作を元に戻したい場合:

この変更は元に戻せません。
もし、引き続きホームディレクトリの設定を利用したい場合は、--config CLI オプションで利用する設定を明示的に指定してください。もしくは、ホームディレクトリ以下に作業ディレクトリを作ってください (ESLint は親ディレクトリからも設定ファイルを探すので)。

RuleTesterのチェックが厳しくなります

🔖 RFC025, #12096, #12955

RuleTesterがより多くの誤りを見つけるようになります。

  • ルールが非標準の node.start/node.endプロパティを参照していた場合にテストが失敗するようになります。代わりに node.rangeプロパティを利用してください。
  • ルールが自動修正を提供するにもかかわらず、自動修正のテスト (output) が書かれていない場合にテストが失敗するようになります。
  • 期待されるエラー内容を指示するerrorsプロパティ内に未知のプロパティがあったとき、テストが失敗するようになります (typo でテストできてなかったという事がなくなります)。

動作を元に戻したい場合:

この変更は元に戻せません。
もし、新たにテストが失敗するようになった場合は、そのルールの処理かテスト内容を更新してください。

新しい ESLintクラスが CLIEngineクラスを置き換えます

🔖 RFC040, #12939

Node.js アプリケーションから ESLint を利用するための API として CLIEngineクラスが提供されています。しかし、CLIEngineクラスは同期 API を提供するため、非同期の処理が必要な並列処理・ES Modules サポート・進捗表示などの機能追加の妨げになっていました。
また、CLIEngineという名前は最初に使うべきクラスであるとの印象を抱きにくく、ブラウザ向けの機能限定版 API である Linterクラスを先に試して「意図通りに動かない」と issue を作る人が多かったです。

ESLint 7 では、この CLIEngineクラスを廃止して、後継となる ESLintクラスを導入しました。ESLintクラスは CLIEngineと同等のメソッドを提供しますが、Promiseを返す非同期メソッドになっています。メソッドの対応は以下の通りです。

CLIEngineESLint
executeOnFiles(patterns)lintFiles(patterns)
executeOnText(text, filePath, warnIgnored)lintText(text, options)
getFormatter(name)loadFormatter(name)
getConfigForFile(filePath)calculateConfigForFile(filePath)
isPathIgnored(filePath)isPathIgnored(filePath)
static outputFixes(results)static outputFixes(results)
static getErrorResults(results)static getErrorResults(results)
static getFormatter(name)(削除)
addPlugin(pluginId, definition)pluginsコンストラクタ オプション
getRules()(未実装)
resolveFileGlobPatterns()(削除)

動作を元に戻したい場合:

現在 CLIEngineクラスは広く利用されているため、少なくとも1年間は削除されないはずです。引き続き利用することができます。
しかし、今後 CLIEngineのコードは凍結され、バグ修正や機能追加が行われません。例えば、ESLint 7.x では並列処理・ES Modules サポート・進捗表示の機能が追加される予定ですが、それらは ESLintクラスのみに実装され、CLIEngineクラスからは利用できません。早めの移行をお勧めします。

✨ 本体への機能追加

RuleTestersuggestionsテストでmessageId/dataを利用できます

🔖 #12635

RuleTestersuggestionsのテストにて、messageプロパティの代わりにmessageId/dataプロパティペアを用いてテストできるようになりました。

const{RuleTester}=require("eslint")construle=require("../../../lib/rules/a-rule")newRuleTester("a-rule",rule,{valid:[],invalid:[{code:"foo",errors:[{messageId:"error",data:{name:"foo"},suggestions:[{messageId:"suggest",data:{name:"foo"},output:"bar"}],}],},],})

💡 新しいルール

default-case-last

🔖 #12668

default句をswitch文の末尾以外に書くことを禁止するルールが追加されました。

/*eslint default-case-last: error *///✘ BADswitch(foo){default:breakcase0:breakcase1:break}

» Online Demo

no-restricted-exports

🔖 #12546

特定の名前の ES Modules エクスポートを禁止するルールが追加されました。

/*eslint no-restricted-exports: [error, { restrictedNamedExports: [foo, bar] }] *///✘ BADexportfunctionfoo(){}letbar=0export{bar}

» Online Demo

no-useless-backreference

🔖 #12690

正規表現中の無意味な後方参照を禁止するルールが追加されました。

/*eslint no-useless-backreference: error *///✘ BADleta=/foo\1(bar)/

» Online Demo

🔧 オプションが追加されたルール

array-callback-return: checkForEach

🔖 #12646

forEach()メソッドのコールバックについてもreturn文をチェックするオプションが追加されました。

/*eslint array-callback-return: [error, { checkForEach: true }] *///✘ BADlist.forEach(x=>{returnx*2})list.forEach(x=>x*2)//✔ GOODlist.forEach(x=>{x*2})

» Online Demo

array-element-newline: ArrayExpression and ArrayPattern

🔖 #11796

配列リテラルと分割代入の配列パターンとで別々の設定を行うためのオプションが追加されました。

/*eslint array-element-newline: [error, { ArrayExpression: always, ArrayPattern: never }] *///✘ BADletfoo=[1,2]let[a,b]=foo

» Online Demo

indent: offsetTernaryExpressions

🔖 #12556

三項演算子の2項目と3項目のインデントをつけるオプションが追加されました。

/*eslint indent: [error, 4, { offsetTernaryExpressions: true }] *///✘ BADletfoo=cond?()=>{doSomething()}:()=>{doSomething()}//✔ GOODletbar=cond?()=>{doSomething()}:()=>{doSomething()}

» Online Demo

indent: outerIIFEBody:"off"

🔖 #12706

トップレベルの即時関数呼び出しのインデントを検証しないオプションが追加されました。

/*eslint indent: [error, 4, { outerIIFEBody: "off" }]*///✔ GOOD(function(){functionfoo(x){returnx+1;}})();

» Online Demo

no-extra-boolean-cast: enforceForLogicalOperands

🔖 #12734

論理式のオペランドでも不要な明示的な boolean型変換を禁止するオプションが追加されました。

/*eslint no-extra-boolean-cast: [error, { enforceForLogicalOperands: true }] *///✘ BADif(!!bar||Boolean(baz));

» Online Demo

no-magic-numbers: BigInt in the ignore option

🔖 #12701

ignoreオプションが新たに文字列を受け入れるようになりました。各文字列は BigInt リテラルとして有効な文字列である必要があります。

/*eslint no-magic-numbers: [error, { ignore: ["123n"] }] *///✔ GOODif(foo===123n);//✘ BADif(foo===456n);

» Online Demo

no-void: allowAsStatement

🔖 #12613

式文の最初に書くvoid式を許可するオプションが追加されました。

/*eslint no-void: [error, { allowAsStatement: true }] *///✔ GOODvoiddoSomething()void(async()=>{doSomething()})().catch(handleError)//✘ BADleta=voiddoSomething()

» Online Demo



Viewing all articles
Browse latest Browse all 9042

Trending Articles