ESLint と Prettier 設定 - Svelte 5 対応

Svelte 5 / SvelteKit 2.x プロジェクトで コード品質を保つための二本柱 が、ESLint と Prettier です。どちらも JavaScript エコシステムの標準ツールですが、Svelte では .svelte ファイル(単一ファイルコンポーネント)の扱いが特殊なため、専用プラグインと正しい設定が必要になります。

この記事では、まず sv add による最短セットアップを紹介し、次にその内側で何が起きているかを理解できるよう手動セットアップも解説します。VS Code / Cursor でのエディタ統合と、よくあるトラブルシューティングまでカバーします。

この記事で学べること

  • ESLint と Prettier のそれぞれの役割と、Svelte プロジェクトでの必要性
  • sv add による最速セットアップ
  • flat config 形式での手動セットアップ(Svelte 5 + TypeScript 対応)
  • VS Code / Cursor でのエディタ統合
  • Prettier と ESLint の衝突回避
  • よくある問題とその解決策

なぜ ESLint と Prettier が必要か

「SvelteKit には svelte-check が標準で付いているのに、さらに ESLint も必要なのか?」という疑問は、Svelte コミュニティでもしばしば議論されます。結論から言えば、三者は役割が異なるため、併用するのが実務での定番 です。

ツール役割実行タイミング
Prettierコードの見た目(インデント・改行・引用符等)を機械的に統一保存時・コミット時
ESLintバグの温床や悪いパターン(未使用変数、== の使用、Svelte の非推奨構文等)を検出保存時・CI
svelte-checkTypeScript の型エラーと Svelte コンパイラ警告を検出CI・明示実行時

svelte-check は「コンパイルが通るか」を見るツールで、eslint は「コードの質が高いか」を見るツールです。たとえば未使用の import、any の多用、a11y 違反(<img> の alt 属性忘れ等)、$statelet の混在は svelte-check では検出されませんが、ESLint は検出できます。

小規模プロジェクトなら svelte-check だけでも良い

個人の学習用プロジェクトや 1 ファイルで完結するデモなら、svelte-check だけでも実害は少ないです。しかし チーム開発、外部公開するライブラリ、業務プロジェクト では、ESLint + Prettier の導入は事実上必須と考えてください。チームの誰かが $state を忘れて let で書いたとき、Prettier と ESLint の両輪がなければ気付けません。

典型的なワークフロー

エディタ保存時・コミット時に、それぞれのツールが自動的に走るのが理想形です。

sv add による最速セットアップ

SvelteKit 公式 CLI の sv add を使えば、ESLint と Prettier は 1 コマンドで導入できます。新規プロジェクトの場合、sv create 時にすでに組み込み済みのことも多いですが、後から追加する場合も以下で完結します。

# ESLint を追加
npx sv add eslint

# Prettier を追加
npx sv add prettier

# 両方まとめて追加することも可能
npx sv add eslint prettier

これだけで以下のファイルが自動生成・追記されます。

  • eslint.config.js — ESLint の flat config(Svelte + TypeScript 対応済み)
  • .prettierrc — Prettier の設定
  • .prettierignore — Prettier の除外パターン
  • package.jsonscriptslintformat が追加
  • package.jsondevDependencies に必要なパッケージが追加
sv add の詳細

sv add コマンドの全体像は CLI tools で解説しています。ESLint / Prettier の他にも vitesttailwindcssplaywrightdrizzle など多数のアドオンを追加できます。

生成される package.json の scripts

sv add 実行後、package.json には以下のようなスクリプトが追加されます。

{
  "scripts": {
    "lint": "prettier --check . && eslint .",
    "format": "prettier --write ."
  }
}

開発中は以下のコマンドで実行します。

# フォーマット(自動整形)
pnpm format

# リント(チェックのみ、修正なし)
pnpm lint

手動セットアップ(理解を深めたい人向け)

sv add の中で何が行われているかを理解しておくと、カスタマイズ時やトラブル時に困りません。ここでは flat config 形式(ESLint 9.x 以降の標準)で、Svelte 5 + TypeScript プロジェクト向けに最小構成を組み立てます。

依存パッケージのインストール

pnpm add -D eslint 
  eslint-plugin-svelte 
  svelte-eslint-parser 
  typescript-eslint 
  globals 
  prettier 
  prettier-plugin-svelte 
  eslint-config-prettier

各パッケージの役割は以下の通りです。

パッケージ役割
eslintESLint 本体
eslint-plugin-svelteSvelte 固有のルール(非推奨構文検出、a11y 等)
svelte-eslint-parser.svelte ファイルをパースするためのパーサ
typescript-eslintTypeScript 用のパーサ・ルールセット
globalsブラウザ・Node のグローバル変数定義
prettierPrettier 本体
prettier-plugin-sveltePrettier で .svelte ファイルを整形するプラグイン
eslint-config-prettierESLint と Prettier のルール衝突を無効化

eslint.config.js

プロジェクトルートに eslint.config.js を作成します。flat config は ESLint 9.x 以降の標準形式で、モジュール形式で設定を書く方式です。

// eslint.config.js
import js from '@eslint/js';
import ts from 'typescript-eslint';
import svelte from 'eslint-plugin-svelte';
import prettier from 'eslint-config-prettier';
import globals from 'globals';
import svelteConfig from './svelte.config.js';

export default ts.config(
  // JavaScript 標準ルール
  js.configs.recommended,

  // TypeScript 推奨ルール
  ...ts.configs.recommended,

  // Svelte 推奨ルール
  ...svelte.configs.recommended,

  // Prettier と競合するルールを無効化(必ず最後に置く)
  prettier,
  ...svelte.configs.prettier,

  // グローバル変数の宣言
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node
      }
    }
  },

  // .svelte / .svelte.ts / .svelte.js 固有のパーサ設定
  {
    files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
    languageOptions: {
      parserOptions: {
        projectService: true,
        extraFileExtensions: ['.svelte'],
        parser: ts.parser,
        svelteConfig
      }
    }
  },

  // 除外パターン
  {
    ignores: ['build/', '.svelte-kit/', 'dist/', 'node_modules/']
  }
);
svelteConfig を parserOptions に渡すのが必須

Svelte 5 では parserOptions.svelteConfigsvelte.config.js の内容を渡すことで、Runes($state$derived 等)を正しく認識します。これを忘れると .svelte.ts ファイル内の Runes が「未定義シンボル」として誤検出されます。

.prettierrc

Prettier の設定はプロジェクトルートに .prettierrc(JSON 形式)または .prettierrc.js として置きます。

{
  "useTabs": true,
  "singleQuote": true,
  "trailingComma": "none",
  "printWidth": 100,
  "plugins": ["prettier-plugin-svelte"],
  "overrides": [
    {
      "files": "*.svelte",
      "options": {
        "parser": "svelte"
      }
    }
  ]
}
Svelte 本体のリポジトリと同じスタイル

上記の設定は Svelte / SvelteKit 公式リポジトリで使われているスタイルに揃えています。「useTabs: true」や「singleQuote: true」は好みで変えても問題ありませんが、チームや OSS 貢献を考えるならこの形が最も馴染みやすいでしょう。

.prettierignore

Prettier が触らないファイルを指定します。

# 自動生成ファイル
.svelte-kit/
build/
dist/
node_modules/
pnpm-lock.yaml
package-lock.json
yarn.lock

# ビルド成果物
*.min.js
*.min.css

package.json の scripts 追加

{
  "scripts": {
    "dev": "vite dev",
    "build": "vite build",
    "preview": "vite preview",
    "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
    "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
    "format": "prettier --write .",
    "lint": "prettier --check . && eslint ."
  }
}

VS Code / Cursor での統合設定

エディタで保存時に自動フォーマット・リントが走るようにすると、開発体験が大きく向上します。

推奨拡張機能

プロジェクトルートに .vscode/extensions.json を作成し、推奨拡張機能を宣言します。

{
  "recommendations": [
    "svelte.svelte-vscode",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode"
  ]
}

Cursor の場合、VS Code 用の拡張機能がそのまま使えます。

ワークスペース設定

.vscode/settings.json に以下を記述することで、保存時の自動フォーマットと ESLint による自動修正を有効にできます。

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "[svelte]": {
    "editor.defaultFormatter": "svelte.svelte-vscode"
  },
  "eslint.validate": [
    "javascript",
    "typescript",
    "svelte"
  ],
  "svelte.enable-ts-plugin": true
}
svelte ファイルは Svelte for VS Code が整形

Prettier が .svelte を整形する場合と、Svelte for VS Code 拡張機能が整形する場合の 2 通りがありますが、後者を使うのが最も安定します。内部的には prettier-plugin-svelte を呼び出しているため、Prettier 設定 (.prettierrc) の内容がそのまま反映されます。

Prettier と ESLint の衝突回避

Prettier と ESLint はどちらも「コードの見た目」に関するルールを持つため、素朴に併用すると衝突します。たとえば ESLint の indent ルールと Prettier のインデント設定が違うと、片方を通すともう片方で怒られる無限ループになります。

これを防ぐのが eslint-config-prettier です。これは Prettier と競合する ESLint ルールを全て無効化する だけの設定で、eslint.config.js最後 に読み込むのが鉄則です。

// eslint.config.js の抜粋(抜粋・再掲)
export default ts.config(
  js.configs.recommended,
  ...ts.configs.recommended,
  ...svelte.configs.recommended,

  // ↓ 必ず最後に置く(上のルールを上書きする形で Prettier と競合する分を無効化)
  prettier,
  ...svelte.configs.prettier,
);
順序を間違えると効かない

prettier 設定は 必ず js.configs.recommendedsvelte.configs.recommended より後 に配置してください。ESLint の flat config は「後勝ち」なので、順序を間違えると衝突ルールが消えません。

pre-commit フックでの自動化(オプション)

チーム開発では、コミット前にリントとフォーマットを強制する仕組みを入れるのが一般的です。husky + lint-staged の組み合わせが最も普及しています。

pnpm add -D husky lint-staged
npx husky init

.husky/pre-commit を以下の内容に編集します。

pnpm exec lint-staged

package.json に以下を追加します。

{
  "lint-staged": {
    "*.{js,ts,svelte}": [
      "prettier --write",
      "eslint --fix"
    ],
    "*.{md,json,yml,yaml}": [
      "prettier --write"
    ]
  }
}

これで git commit 時に、ステージングされたファイルだけを対象に自動整形+リントが走り、エラーがあればコミットが中断されます。

よくある問題とトラブルシューティング

.svelte.ts ファイル内の Runes が未定義扱いされる

ESLint を実行すると '$state' is not defined のようなエラーが出る場合は、parserOptions.svelteConfig の設定漏れが原因です。

// NG: svelteConfig を渡していない
{
  files: ['**/*.svelte', '**/*.svelte.ts'],
  languageOptions: {
    parserOptions: {
      parser: ts.parser
    }
  }
}

// OK
import svelteConfig from './svelte.config.js';
// ...
{
  files: ['**/*.svelte', '**/*.svelte.ts'],
  languageOptions: {
    parserOptions: {
      parser: ts.parser,
      svelteConfig  // ← これが必要
    }
  }
}

Prettier が .svelte を整形してくれない

prettier-plugin-svelte がインストールされていない、または .prettierrcplugins に指定されていない可能性があります。

# インストール確認
pnpm list prettier-plugin-svelte

# .prettierrc で明示的に読み込む
{
  "plugins": ["prettier-plugin-svelte"]
}

ESLint と Prettier が毎回衝突する

前述のとおり、eslint-config-prettiereslint.config.js最後 に置いているか確認してください。

実行が遅い

TypeScript のプロジェクトリファレンスを使うプロジェクトでは、ESLint の実行が非常に遅くなることがあります。その場合は以下を検討してください。

  • parserOptions.projectService: trueproject: './tsconfig.json' に変更し、必要最小限の tsconfig だけ参照する
  • .eslintignore(flat config では ignores プロパティ)で不要なディレクトリを除外
  • CI では eslint --cache を使う
// eslint.config.js に .eslintcache を無視
{
  ignores: ['build/', '.svelte-kit/', 'dist/', 'node_modules/', '.eslintcache']
}

2026 年 4 月時点の安定性

eslint-plugin-svelte は 2026 年 4 月時点で v3.17.x 系が安定版です。Svelte 5 の Runes($state$derived$effect$props{#snippet}{@render} 等)は全て正式サポート済みで、$state.eager のような新しいルーンも追随しています。

バージョン固定を推奨

eslint-plugin-svelte はリリース頻度が高い(週〜隔週)ので、業務プロジェクトでは package.json でバージョン固定を推奨します。

{
  "devDependencies": {
    "eslint-plugin-svelte": "3.17.0"
  }
}

まとめ

Svelte 5 / SvelteKit 2.x プロジェクトでは、ESLint と Prettier の併用が事実上の標準です。sv add で最短導入し、flat config の仕組みを理解しておけば、後からのカスタマイズにも困りません。

  • Prettier: 見た目を統一
  • ESLint: バグや悪いパターンを検出
  • svelte-check: 型検証
  • svelteConfig を parserOptions に渡す ことで Runes を正しく認識
  • eslint-config-prettier は必ず最後 に読み込む
  • VS Code 統合 で保存時自動整形+自動修正

次のステップ