Skip to content
← Back to rules

import/extensions 制限

何をしますか

一部のファイル解決アルゴリズムでは、インポートのソースパス内でファイル拡張子を省略できます。 たとえば、現在のところ ESM/import をサポートしていない Node の解決器は、CJS でデフォルトで拡張子が自動的に解決されるため、./foo/bar を絶対パス /User/someone/foo/bar.js に解決できます。 解決器によっては、さらに多くの拡張子を自動的に解決できるように設定できます。 コードベース全体でファイル拡張子の使用を一貫性を持たせるために、このルールは特定のファイル拡張子の使用を強制するか、禁止することができます。

なぜ問題なのか

ESM ベースのファイル解決アルゴリズム(例:Vite が提供するもの)は、パフォーマンス向上の観点から、ファイル拡張子を明示することを推奨しています。

このルールに対して誤りとされる例:

以下のパターンは、設定が "always" に設定されている場合に問題とされます:

js
import foo from "./foo";
import bar from "./bar";
import Component from "./Component";
import foo from "@/foo";

以下のパターンは、設定が "never" に設定されている場合に問題とされます:

js
import foo from "./foo.js";
import bar from "./bar.json";
import Component from "./Component.jsx";
import express from "express/index.js";

このルールに対して正しい例:

以下のパターンは、設定が "always" に設定されている場合に問題とされません:

js
import foo from "./foo.js";
import bar from "./bar.json";
import Component from "./Component.jsx";
import * as path from "path";
import foo from "@/foo.js";

以下のパターンは、設定が "never" に設定されている場合に問題とされません:

js
import foo from "./foo";
import bar from "./bar";
import Component from "./Component";
import express from "express/index";
import * as path from "path";

拡張子ごとの設定例

js
// 設定: { "vue": "always", "ts": "never" }
import Component from "./Component.vue"; // ✓ OK - .vue は "always" に設定済み
import utils from "./utils"; // ✓ OK - .ts は "never" に設定済み
import styles from "./styles.css"; // ✓ OK - .css は設定されていないため無視される

// 設定: ["ignorePackages", { "js": "never", "ts": "never" }]
import foo from "./foo"; // ✓ OK - 拡張子なし
import bar from "lodash/fp"; // ✓ OK - パッケージインポート、無視 (ignorePackages が true に設定されている)

設定

このルールは3種類の設定を受け付けます。

  1. グローバルルール(文字列): "always", "never", または "ignorePackages"
jsonc
{
  "rules": {
    // すべてのインポート(パッケージ含む)に対して拡張子を要求する
    // 例:`import React from 'react';` は許可されなくなる
    // `always` を使用する際は、一般に `ignorePackages` を `true` に設定すべきです
    "import/extensions": ["error", "always"],
  },
}
  1. 拡張子ごとのルール(オブジェクト): { "js": "always", "jsx": "never", ... }
jsonc
{
  "rules": {
    "import/extensions": [
      "error",
      // 拡張子ごとのルール:
      // .js インポートには拡張子を要求し、.ts インポートには禁止
      { "js": "always", "ts": "never", "ignorePackages": true },
    ],
  },
}
  1. 併用(配列): ["error", "always", { "js": "never" }] または ["error", { "js": "always" }]
jsonc
{
  "rules": {
    "import/extensions": [
      "error",
      "always", // デフォルトで、すべてのインポートに拡張子を要求
      {
        "ts": "never", // グローバル値を上書きし、特定のファイルタイプのインポートで拡張子の使用を禁止
        "ignorePackages": true,
      },
    ],
  },
}

デフォルト動作(設定なし): すべてのインポート(あらゆる種類)は通過する。 未設定のファイル拡張子は無視されるため、誤検出を回避できる。

このルールは、以下のプロパティを持つ設定オブジェクトを受け付けます。

checkTypeImports

type: boolean

default: false

拡張子ルールを適用する際に、型インポートもチェックするかどうか。

ts
// checkTypeImports が `false` なら、
// これらのインポートに拡張子があるかどうかは関係なく、どちらも常に許可される:
import type { Foo } from "./foo";
import type { Foo } from "./foo.ts";

ignorePackages

type: boolean

default: false

拡張子ルールを適用する際に、パッケージインポートを無視するかどうか。

IMPORTANT

本ルールを always に設定する場合は、同時に ignorePackagestrue に設定する必要があります。 それ以外の場合、拡張子なしのパッケージインポート(例:import React from 'react';)が禁止されてしまうため、望ましくなく、修正もできません。

ブール値のオプション(拡張子ごとではなく)であり、パッケージインポートを "always" ルールから除外します。

設定オブジェクトで設定可能:["error", "always", { "ignorePackages": true }]

レガシー簡易表記:["error", "ignorePackages"]["error", "always", { "ignorePackages": true }] と同等です。

  • "always" と共に: true に設定された場合、パッケージインポート(例:lodash, @babel/core)は拡張子を必要としない
  • "never" と共に: このオプションは効果がない;パッケージインポートでは依然として拡張子が禁止される

例:["error", "always", { "ignorePackages": true }]import foo from "lodash" を許可するが、import bar from "./bar.js" には拡張子を要求する

pathGroupOverrides

type: array

default: []

独自のインポート仕様用のパスグループのオーバーライド。

カスタムインポートプロトコル(モノレポツール、カスタム解決器)用のパターン-アクションペアの配列。 各オーバーライドには以下のように指定:{ "pattern": "<glob-pattern>", "action": "enforce" | "ignore" }

パターンマッチング: グロブパターン(*, **, {a,b})を使用してインポート仕様をマッチング。 注意:パターンマッチングは、高速な fast-glob ライブラリを用いた Rust で行われており、元の ESLint ルールで使われる JavaScript のグロブライブラリとは異なる可能性があります。

アクション:

  • "enforce": 通常の拡張子検証を適用(グローバル/拡張子ごとのルールを尊重)
  • "ignore": マッチするインポートに対してすべての拡張子検証をスキップ

優先順位: 最初に一致したパターンが適用される。

:

json
{
  "pattern": "rootverse{*,*/**}",
  "action": "ignore"
}

rootverse+debug:src, rootverse+bfe:src/symbols からのインポートをマッチし、 拡張子の有無に関わらず無視する。

pathGroupOverrides[n]

type: object

pathGroupOverrides[n].action

type: "enforce" | "ignore"

パスグループのオーバーライドに対するアクション。

マッチする独自のインポート仕様に対するインポート拡張子の検証方法を決定します。

"enforce"

マッチするインポートに対して拡張子検証を強制する(設定に基づいて拡張子を要求)。

"ignore"

マッチするインポートを完全に無視する(すべての拡張子検証をスキップ)。

pathGroupOverrides[n].pattern

type: string

インポート仕様をマッチさせるためのグロブパターン。このマッチングには Rust 用の fast-glob ライブラリが使用されます。

使い方

このルールを有効化するには、設定ファイルまたは CLI を使って次のように使用できます:

json
{
  "plugins": ["import"],
  "rules": {
    "import/extensions": "error"
  }
}
bash
oxlint --deny import/extensions --import-plugin

参照