この移行ガイドでは、Svelteバージョン3から4に移行する方法の概要を説明します。各変更の詳細については、リンクされたPRを参照してください。 移行スクリプトを使用して、これらの一部を自動的に移行します: npx svelte-migrate@latest svelte-4
あなたがライブラリ作成者の場合は、Svelte4のみをサポートするか、Svelte3もサポートできるかどうかを検討してください。 重大な変更のほとんどは多くの人に影響を与えないので、これは簡単に実現できるかもしれません。また、peerDependencies
のバージョン範囲も忘れずに更新してください。
最低限必要なバージョンpermalink
- Node16以上にアップグレードしてください。それ以下のバージョンはもうサポートされていません。(#8566)
- SvelteKitを使用している場合、1.20.4以上にアップグレードしてください (sveltejs/kit#10172)
- SvelteKit を使わずに Vite を使っている場合は、
vite-plugin-svelte
2.4.1以上にアップグレードしてください (#8516) - webpackを使用している場合は、webpack5以上に、
svelte-loader
は3.1.8以上にアップグレードしてください。それ以下のバージョンはサポートされなくなりました。(#8515, 198dbcf) - Rollupを使用している場合は、
rollup-plugin-svelte
7.1.5以上にアップグレードしてください (198dbcf) - TypeScriptを使用している場合は、TypeScript5以上にアップグレードしてください。それ以下のバージョンでも動作する可能性はありますが、保証はできません。(#8488)
バンドラーのブラウザ条件permalink
ブラウザ用のフロントエンドバンドルをビルドするとき、バンドラーはbrowser
条件を指定しなければならなくなりました。SvelteKitとViteは自動的にこれを処理します。他のものを使っている場合は、onMount
のようなライフサイクルのコールバックが呼ばれないことがあるので、モジュールの解決設定を更新する必要があります。
- Rollup の場合は、
@rollup/plugin-node-resolve
プラグインのオプションでbrowser: true
を設定することでこれを行います。詳しくはrollup-plugin-svelte
ドキュメントを参照してください。 - wepback では、
"browser"
をconditionNames
配列に追加します。また、alias
を設定している場合は、それを更新する必要があるかもしれません。詳しくはsvelte-loader
のドキュメントを参照してください。
(#8516)
CJS関連の出力の削除permalink
Svelteはコンパイラ出力としてCommonJS (CJS)フォーマットをサポートしなくなり、svelte/register
フックとCJSランタイムバージョンも削除されました。CJS出力フォーマットをまだ使用する必要がある場合は、ビルド後のステップでSvelteのESM出力をCJSに変換するバンドラーの使用を検討してください。(#8613)
Svelteの関数のより厳密な型permalink
createEventDispatcher
、Action
、ActionReturn
、およびonMount
には、より厳密な型が追加されました。
createEventDispatcher
はペイロードがオプション、必須、または存在しないことを指定できるようになり、それに応じてコールサイトがチェックされます (#7224)
ts
import {createEventDispatcher } from 'svelte';constdispatch =createEventDispatcher <{optional : number | null;required : string;noArgument : null;}>();Expected 2-3 arguments, but got 1.2554Expected 2-3 arguments, but got 1.Argument of type '"surprise"' is not assignable to parameter of type 'null | undefined'.2345Argument of type '"surprise"' is not assignable to parameter of type 'null | undefined'.// Svelte バージョン 3:dispatch ('optional');dispatch ('required'); // 詳細引数は省略できますExpected 2-3 arguments, but got 1.2554Expected 2-3 arguments, but got 1.dispatch ('noArgument', 'surprise'); // 詳細な引数を追加することもできますArgument of type '"surprise"' is not assignable to parameter of type 'null | undefined'.2345Argument of type '"surprise"' is not assignable to parameter of type 'null | undefined'.// TypeScript strict モードを使用した Svelte バージョン 4:dispatch ('optional');dispatch ('required'); // エラー、引数がありませんdispatch ('noArgument', 'surprise'); // エラー、引数を渡すことができません
Action
とActionReturn
のデフォルトのパラメータタイプはundefined
になりました。つまり、この action がパラメータを受け取るように指定したい場合は、このように generic を型付けする必要があります。移行スクリプトはこれを自動的に移行します (#7442)
const action: Action = (node, params) => { .. } // 何らかの方法でparamsを使用すると、エラーになります
const action: Action<HTMLElement, string> = (node, params) => { .. } // paramsはstring型です
onMount
に非同期な関数を返した場合、型エラーを表示するようになりました。これはおそらくバグだからです。コンポーネントの破棄時にコールバックが呼び出されることを期待しているのだと思いますが、それは同期的に関数を返した場合にのみ動作します。
// この変更によって実際のバグが明らかになった例
onMount(
// onMountに渡される関数が非同期であるため、someCleanup()が呼び出されない
async () => {
const something = await foo();
// onMountに渡された関数が同期されているため、someCleanup()が呼び出される。
() => {
foo().then(something => ..
// ..
return () => someCleanup();
}
);
Svelteを使用したカスタム要素permalink
Svelteでのカスタム要素の作成が大幅に改善されました。tag
オプションは廃止され、新しいcustomElement
オプションが採用されました:
<svelte:options tag="my-component" />
<svelte:options customElement="my-component" />
この変更は、高度なユースケースのためのより詳細な設定を可能にするために行われました。移行スクリプトは、コードを自動的に調整します。プロパティの更新タイミングも若干変更されました。(#8457)
SvelteComponentTypedは非推奨ですpermalink
SvelteComponent
がすべての型付け機能を持つようになったため、SvelteComponentTyped
は非推奨です。すべてのSvelteComponentTyped
インスタンスをSvelteComponent
に置き換えてください。
import { SvelteComponentTyped } from 'svelte';
import { SvelteComponent } from 'svelte';
export class Foo extends SvelteComponentTyped<{ aProp: string }> {}
export class Foo extends SvelteComponent<{ aProp: string }> {}
以前、コンポーネントのインスタンスタイプとしてSvelteComponent
を使用していた場合、やや不透明なタイプエラーが表示されることがありますが、これは: typeof SvelteComponent
を: typeof SvelteComponent<any>
に変更することで解決します。
<script>
import ComponentA from './ComponentA.svelte';
import ComponentB from './ComponentB.svelte';
import { SvelteComponent } from 'svelte';
let component: typeof SvelteComponent;
let component: typeof SvelteComponent<any>;
function choseRandomly() {
component = Math.random() > 0.5 ? ComponentA : ComponentB;
}
</script>
<button on:click={choseRandomly}>random</button>
<svelte:element this={component} />
移行スクリプトは両方を自動的に実行します。 (#8512)
トランジションはデフォルトでlocalになりましたpermalink
ページナビゲーションの混乱を防ぐため、トランジションはデフォルトでlocalになりました。"local"とは、ネストされたコントロールフローブロック(each/if/await/key
)内にあり、直接の親ブロックではなく、その上のブロックが生成/破棄された場合にはトランジションが再生されないことを意味します。次の例では、slide
のイントロアニメーションは、success
がfalse
からtrue
になったときだけ再生されますが、show
がfalse
からtrue
になったときは再生されません:
{#if show}
...
{#if success}
<p in:slide>Success</p>
{/each}
{/if}
トランジションをグローバルにするには、|global
モディファイアを追加してください。そうすると、上記のいずれのコントロールフローブロックが作成/破棄されたときにもトランジションが再生されます。移行スクリプトは自動的にこれを行います。(#6686)
デフォルトのスロットバインディングpermalink
デフォルトのスロットバインディングが名前付きスロットに公開されることはなくなりました:
<script>
import Nested from './Nested.svelte';
</script>
<Nested let:count>
<p>
count in default slot - is available: {count}
</p>
<p slot="bar">
count in bar slot - is not available: {count}
</p>
</Nested>
例えば、デフォルトのスロットがリストにあって、指定されたスロットがそうでない場合、動作は未定義なので、これはスロットバインディングをより一貫性のあるものにします。(#6049)
プリプロセッサpermalink
プリプロセッサの適用順序が変更されました。現在、プリプロセッサはマークアップ、スクリプト、スタイルの順に実行されます。
ts
import {preprocess } from 'svelte/compiler';const {code } = awaitpreprocess (source ,[{markup : () => {console .log ('markup-1');},script : () => {console .log ('script-1');},style : () => {console .log ('style-1');}},{markup : () => {console .log ('markup-2');},script : () => {console .log ('script-2');},style : () => {console .log ('style-2');}}],{filename : 'App.svelte'});// Svelte 3 logs:// markup-1// markup-2// script-1// script-2// style-1// style-2// Svelte 4 logs:// markup-1// script-1// style-1// markup-2// script-2// style-2
これは、例えばMDsveX
を使用している場合に影響する可能性があります。もし使用している場合は、他のスクリプトやスタイルプリプロセッサよりも前に実行するように変更してください。
preprocess: [
vitePreprocess(),
mdsvex(mdsvexConfig)
mdsvex(mdsvexConfig),
vitePreprocess()
]
各プリプロセッサにもname
が必要です。(#8618)
新しいeslintパッケージpermalink
eslint-plugin-svelte3
は非推奨です。Svelte4ではまだ動くかもしれませんが、保証はしません。新しいパッケージeslint-plugin-svelteに切り替えることをお勧めします。移行方法はこのGithubの投稿を参照してください。あるいは、npm create svelte@latest
を使って新しいプロジェクトを作成し、eslint (場合によってはTypeScriptも) オプションを選択して、関連ファイルを既存のプロジェクトにコピーすることもできます。
その他の変更点permalink
- outroing要素に
inert
属性が適用されるようになり、支援技術から見えなくなり、インタラクションを防ぐことができるようになりました。(#8628) - ランタイムが
classList.toggle(name, boolean)
を使うようになりました。これらのブラウザをサポートする必要がある場合は、polyfill を使うことを検討してください。(#8629) - ランタイムが
CustomEvent
コンストラクタを使用するようになりました。これらのブラウザをサポートする必要がある場合は、polyfill の使用を検討してください。(#8775) svelte/store
からStartStopNotifier
インターフェース(writable
などのcreate関数に渡される)を使ってスクラッチから独自のストアを実装する場合、set関数に加えてupdate関数を渡す必要があります。これはストアを使用している人や、既存のSvelteストアを使用してストアを作成している人には影響しません。(#6750)derived
に渡されるストアの代わりに、不正な値に対してエラーを投げるようになりました。(#7947)svelte/internal
の型定義が削除され、パブリックAPIではない内部メソッドの使用を推奨しないようにしました。これらのほとんどはSvelte5で変更されると思われます。- DOMノードの削除がバッチ処理されるようになり、順序が若干変更されました。このため、これらの要素で
MutationObserver
を使用している場合、イベントの発生順序に影響を与える可能性があります。 (#8763) svelte.JSX
名前空間を使用してグローバルタイピングを拡張していた場合はsvelteHTML
名前空間を使用するように移行する必要があります。同様にsvelte.JSX
名前空間から型定義を使用していた場合は、代わりにsvelte/elements
から型定義を使用するように移行する必要があります。何をすべきかについての詳細はこちらを参照してください。