コンテンツへスキップ

@stylistic/

semi

JavaScriptでは、各文の最後にセミコロンを付ける必要はありません。多くの場合、JavaScriptエンジンはセミコロンを特定の位置に配置すべきであると判断し、自動的に追加します。この機能は**自動セミコロン挿入(ASI)**として知られており、JavaScriptのより物議を醸す機能の1つと考えられています。例えば、次の行はどちらも有効です。

js
var name = "ESLint"
var website = "eslint.org";

最初の行では、JavaScriptエンジンは自動的にセミコロンを挿入するため、これは構文エラーとは見なされません。JavaScriptエンジンは依然として行を解釈する方法を知っており、行末が文の終わりを示していることを認識しています。

ASIに関する議論では、一般的に2つの考え方があります。1つは、ASIが存在しないかのように扱い、常に手動でセミコロンを含めるべきだという考え方です。その理由は、セミコロンを常に含める方が、いつ必要でいつ不要かを覚えるよりも簡単であり、エラーが発生する可能性を減らすことができるためです。

しかし、ASIメカニズムは、セミコロンを使用している人にとって、場合によっては厄介な場合があります。例えば、次のコードを考えてみましょう。

js
return
{
    name: "ESLint"
};

これはオブジェクトリテラルを返す`return`文のように見えますが、JavaScriptエンジンはこのコードを次のように解釈します。

js
return;
{
    name: "ESLint";
}

事実上、`return`文の後にセミコロンが挿入され、その下のコード(ブロック内のラベル付きリテラル)は到達不能になります。このルールとno-unreachableルールは、このような場合からコードを保護します。

一方、セミコロンは自動的に挿入されるため、オプションであり、手動で挿入する必要はないと言う人もいます。しかし、ASIメカニズムは、セミコロンを使用しない人にとっても厄介な場合があります。例えば、次のコードを考えてみましょう。

js
var globalCounter = { }

(function () {
    var n = 0
    globalCounter.increment = function () {
        return ++n
    }
})()

この例では、最初の行の後にセミコロンは挿入されず、ランタイムエラーが発生します(空のオブジェクトが関数のように呼び出されるため)。no-unexpected-multilineルールは、このような場合からコードを保護します。

ASIはコーディングスタイルにより多くの自由度を与えますが、セミコロンを使用するかどうかに関わらず、コードが予期しない動作をする可能性もあります。したがって、ASIが発生する時と発生しない時を知り、ESLintでこれらの潜在的に予期しないケースからコードを保護することが最善です。要約すると、Isaac Schlueterによってかつて説明されたように、`\n`文字は(セミコロンと同様に)常に文を終了します。ただし、次のいずれかが当てはまる場合を除きます。

  1. 文に閉じられていない括弧、配列リテラル、またはオブジェクトリテラルが含まれているか、または文を終了する有効な方法ではない他の方法で終了します。(例えば、`.`または`,`で終わる場合)
  2. 行が`--`または`++`です(この場合、次のトークンをデクリメント/インクリメントします)。
  3. `for()`、`while()`、`do`、`if()`、または`else`であり、`{`がありません。
  4. 次の行が`[`、`(`、`+`、`*`、`/`、`-`、`,`、`.`、または単一の式内の2つのトークンの間でのみ見つかるその他の二項演算子で始まります。

ルール詳細

このルールは、セミコロンの一貫した使用を強制します。

オプション

このルールには、文字列オプションとオブジェクトオプションの2つのオプションがあります。

文字列オプション

  • "always"(デフォルト)は、文の最後にセミコロンを要求します。
  • "never"は、文の最後にセミコロンを許可しません(`[`、`(`、`/`、`+`、または`-`で始まる文を明確にする場合を除く)。

オブジェクトオプション("always"の場合)

  • "omitLastInOneLineBlock": trueは、その中括弧(したがってブロックの内容)が同じ行にあるブロックの最後のセミコロンを許可しません。
  • "omitLastInOneLineClassBody": trueは、その中括弧(したがってクラスボディの内容)が同じ行にあるクラスボディの最後のセミコロンを許可しません。

オブジェクトオプション("never"の場合)

  • "beforeStatementContinuationChars": "any"(デフォルト)は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、文の最後にあるセミコロン(またはセミコロンがないこと)を無視します。
  • "beforeStatementContinuationChars": "always"は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、文の最後にセミコロンを要求します。
  • "beforeStatementContinuationChars": "never"は、次の行が`[`、`(`、`/`、`+`、または`-`で始まったとしても、ASIの危険性がない場合は、文の最後にセミコロンを許可しません。

**注記:**beforeStatementContinuationCharsは、クラスフィールドは文ではないため、クラスフィールドには適用されません。

always

デフォルトの"always"オプションを使用した場合の、このルールに違反するコードの例

js
/*eslint @stylistic/semi: ["error", "always"]*/

var name = "ESLint"
object.method = function() { // ... }
class Foo { bar = 1
}
incorrect

デフォルトの"always"オプションを使用した場合の、このルールに準拠するコードの例

js
/*eslint @stylistic/semi: "error"*/

var name = "ESLint";

object.method = function() {
    // ...
};

class Foo {
    bar = 1;
}
correct

omitLastInOneLineBlock

"always", { "omitLastInOneLineBlock": true }オプションを使用したこのルールに準拠する追加のコードの例

js
/*eslint @stylistic/semi: ["error", "always", { "omitLastInOneLineBlock": true}] */

if (foo) { bar() }

if (foo) { bar(); baz() }

function f() { bar(); baz() }

class C {
    foo() { bar(); baz() }

    static { bar(); baz() }
}
correct

omitLastInOneLineClassBody

"always", { "omitLastInOneLineClassBody": true }オプションを使用したこのルールに準拠する追加のコードの例

js
/*eslint @stylistic/semi: ["error", "always", { "omitLastInOneLineClassBody": true}] */

export class SomeClass{
    logType(){
        console.log(this.type);
        console.log(this.anotherType);
    }
}

export class Variant1 extends SomeClass{type=1}
export class Variant2 extends SomeClass{type=2; anotherType=3}
correct

never

"never"オプションを使用したこのルールに違反するコードの例

js
/*eslint @stylistic/semi: ["error", "never"]*/

var name = "ESLint"
;
object.method = function() { // ... }
;
class Foo { bar = 1
;
}
incorrect

"never"オプションを使用したこのルールに準拠するコードの例

js
/*eslint @stylistic/semi: ["error", "never"]*/

var name = "ESLint"

object.method = function() {
    // ...
}

var name = "ESLint"

;(function() {
    // ...
})()

import a from "a"
(function() {
    // ...
})()

import b from "b"
;(function() {
    // ...
})()

class Foo {
    bar = 1
}
correct

beforeStatementContinuationChars

"never", { "beforeStatementContinuationChars": "always" }オプションを使用したこのルールに違反する追加のコードの例

js
/*eslint @stylistic/semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */
import a from "a"
(function() { // ... })()
incorrect

"never", { "beforeStatementContinuationChars": "never" }オプションを使用したこのルールに違反する追加のコードの例

js
/*eslint @stylistic/semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */
import a from "a"

;
(function() {
// ... })()
incorrect

使用しない場合

特定の方法でセミコロンの使用(または省略)を強制したくない場合は、このルールをオフにすることができます。

TypeScript固有

ts/semi

@stylistic/ts/member-delimiter-styleルールも参照してください。これにより、`type`と`interface`メンバのデリミタを指定できます。

MITライセンスの下でリリースされています。