correctness/orphan-lifecycle · コンポーネント初期化外での lifecycle 呼び出し
onMount や getContext などをコンポーネント初期化の外で呼ぶと、ランタイムで lifecycle_outside_component エラーになります。
重大度: critical · カテゴリ: correctness
チェック内容
Svelte の lifecycle / context 関数(onMount、onDestroy、beforeUpdate、afterUpdate、createEventDispatcher、getContext、setContext、hasContext、getAllContexts。svelte からの value import が対象で、エイリアスと namespace import も追跡します)のうち、コンポーネント初期化の外での実行が確定している呼び出しを検出します。
.svelte.ts/.svelte.jsrunes モジュールや.svelteの<script module>ブロックのモジュールスコープ- モジュールスコープでインスタンス化されるクラスの constructor 内(同一ファイル)
- SvelteKit の
load関数、form action、エンドポイント/フック handler、initフック内、またはそれらのファイルのトップレベル(典型はload内でのgetContext)
検出対象外:
- 通常の関数内の呼び出し(コンポーネントが初期化中に呼べば合法)。
createContext()。モジュールスコープでの作成が新 context API の公式パターンです。- context を要求しない svelte export(
mount、tickなど)、他モジュールからの同名 import、ファクトリ関数/IIFE/クロスファイルクラス、svelte/legacyのcreateBubbler。
load/handler/init の本体の内側で定義された関数は、そこで実行されるものとして扱い検出します。意図的にそのクロージャを返してコンポーネント側の初期化中に呼ばせる場合は svelte-vitals-disable-next-line correctness/orphan-lifecycle で抑制してください。
なぜ重要か
これらの関数はアクティブなコンポーネントコンテキストを必要とします。getContext/setContext/hasContext/getAllContexts は、ない状態で呼ぶとあらゆる環境でランタイムに lifecycle_outside_component エラーになります。コンパイラはどのパターンも警告なしでコンパイルするため、コードパスが実行されて初めて顕在化します(load 内なら、そのルートへの全アクセスが 500 に)。
onMount/beforeUpdate/afterUpdate/createEventDispatcher はブラウザでは同じエラーを throw します。しかしサーバーでしか実行されない Kit モジュール(+page.server.ts、+server.ts、hooks.server.ts)ではブラウザに到達すること自体がないため、呼び出しは何もしない no-op になります。クラッシュせず、何も起きません。onDestroy だけはそこでも例外です。自前のコンポーネントコンテキストガードを持たないため、呼び出せば依然としてクラッシュしますが、lifecycle_outside_component ではなく素の TypeError になります(load/handler 内なら、そのルートへの全リクエストで 500 になる点は変わりません)。+page.ts/+layout.ts の universal モジュールやコンポーネント内のコードでは、同じコードがブラウザでも実行されるため、9つすべてが lifecycle_outside_component を throw します。
修正方法
import { getContext } from 'svelte';
export async function load({ fetch }) {
const user = getContext('user'); // ❌ lifecycle_outside_component(load はコンポーネント初期化ではない)
return { user: await (await fetch('/api/user')).json() }; // ✅ 代わりにデータを返す
}
呼び出しをコンポーネント初期化へ移します。
<script>
import { setContext } from 'svelte';
let { data } = $props();
setContext('user', () => data.user); // ✅ コンポーネント初期化中(合法)
</script>
共有モジュールでは、モジュールスコープで lifecycle を呼ぶ代わりに、コンポーネントが初期化時に呼ぶ setup 関数として公開してください。
モードによる違い
ありません。このルールが読むのは同じ .svelte / .ts のソースファイルなので、CLI、Vite プラグインのビルド、ライブダッシュボードの静的ベースラインのいずれでも結果は同一で、レンダリング済み HTML の解析で再評価されることもありません。--route で実行範囲を絞ると、このルールは動きません。コンポーネントスコープのルールには、検出を紐づけるルートが無いためです。
無効化
個別に抑制するには、対象行の直前に <!-- svelte-vitals-disable-next-line correctness/orphan-lifecycle --> を置きます。ルールごと無効化するには、次のように設定します。
export default {
rules: {
'correctness/orphan-lifecycle': 'off'
}
};