Svelte 5 が登場
過去最大のリリース
数多くのコントリビューターによる何千ものコミットを含む、約18ヶ月の開発期間を経て、Svelte 5がついに安定版となりました。
これはプロジェクト史上最も重要なリリースです。Svelte 5 は根本から書き直されており、アプリはより速く、より小さく、より信頼性の高いものになります。より一貫性があり、イディオムに沿ったコードを書けるようになります。フレームワークの初心者にとっては、学ぶべきことが少なくなります。
それにもかかわらず、Svelte は Svelte 4 とほぼ完全に後方互換性があります。ほとんどのユーザーにとって、最初のアップグレードは完全にシームレスに行われるでしょう。
{
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"svelte": "^4",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"svelte": "^5",
// …
}
}
Svelteとは?
Svelte は、ウェブ上でユーザーインターフェースを構築するためのフレームワークです。HTML、CSS、JavaScript に基づいた宣言的なコンポーネントコードを、コンパイラを使用して最適化された JavaScript に変換します。
コンパイラが多くの作業をブラウザから npm run build
に移すため、Svelte アプリは小さく高速です。しかし、それ以上に、Svelte はアプリを構築するための楽しく直感的な方法として設計されています。それは、物事を成し遂げることを優先します。
Svelte を支えるチームは、ルーティング、データローディング、サーバーサイドレンダリング、そして最新のウェブサイトやアプリを構築する際の細部の処理を行うアプリケーションフレームワークである SvelteKit も保守しています。
何が変わり、なぜ変わったのか?
まず、ウェブサイトを刷新しました。詳細については、こちらをご覧ください。
Svelte 自体については、まず「なぜ」について説明します。私たちは変化のための変化を好みません。実際、Svelte は 2019 年(Svelte 3 をリリースした時)から現在までの間、他の主要なフレームワークよりも変化が少なく、フロントエンド開発においては非常に長い期間です。そして人々は Svelte 3 と 4 を非常に気に入っており、開発者満足度調査で常に上位にランクインしています。
そのため、変更を加える際には慎重に行っています。
Svelte を使用してより多くの、より大きなアプリケーションを構築する人が増えるにつれて、当初の設計上の決定事項のいくつかの制限がより明確になってきました。たとえば、Svelte 4 では、リアクティビティは完全にコンパイラによって駆動されます。Svelte 4 でリアクティブオブジェクトの単一のプロパティを変更すると、オブジェクト全体が無効になります。なぜなら、それがコンパイラが現実的にできることだからです。一方、他のフレームワークは、シグナルに基づいたきめ細かいリアクティビティを採用し、Svelte のパフォーマンスを追い抜きました。
同様に、コンポーネントの構成は、イベントハンドラーと「スロット付きコンテンツ」をコンポーネントに渡される props とは異なる別々の概念として扱うため、Svelte 4 ではあるべき姿よりも扱いにくくなっています。これは、2019 年にはウェブコンポーネントがコンポーネントの主要な配布メカニズムになる可能性が高く、プラットフォームに合わせたいと考えていたためです。これは間違いでした。
また、リアクティブにステートメントを再実行するための $:
構文は便利なトリックですが、落とし穴であることが判明しました。それは(派生状態と副作用という)本当に分離されるべき2つの概念を混同しており、依存関係は(実行時ではなく)ステートメントがコンパイルされるときに決定されるため、リファクタリングに抵抗し、複雑さの温床となります。
Svelte 5 は、これらの矛盾点と落とし穴を解消します。リアクティブステートを宣言するための明示的なメカニズムであるルーインを導入します。
let count = 0;
let let count: number
count = function $state<0>(initial: 0): 0 (+1 overload)
namespace $state
Declares reactive state.
Example:
let count = $state(0);
$state(0);
状態との対話は変更されていません。他のフレームワークとは異なり、Svelte では count
は単なる数値であり、関数や value
プロパティを持つオブジェクト、または対応する setCount
でしか変更できないものではありません。
function function increment(): void
increment() {
let count: number
count += 1;
var console: Console
The console
module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console
class with methods such as console.log()
, console.error()
and console.warn()
that can be used to write to any Node.js stream.
- A global
console
instance configured to write to process.stdout
and
process.stderr
. The global console
can be used without calling require('console')
.
Warning: The global console object’s methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O
for
more information.
Example using the global console
:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console
class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to stdout
with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()
).
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
See util.format()
for more information.
log({ count: number
count });
}
ルーインは、.svelte
コンポーネントに加えて、.svelte.js
および .svelte.ts
モジュールでも使用できるため、単一のメカニズムを使用して再利用可能なリアクティブロジックを作成できます。
イベントハンドラーは、他の props と同様に props になり、(たとえば) コンポーネントのユーザーが特定のイベントハンドラーを提供したかどうかを知ることが容易になります (これは、コストのかかる設定作業を回避するのに役立ちます)。または、任意のイベントハンドラーを何らかの要素に広げることができます。これは、ライブラリの作成者にとって特に重要です。
そして、コンポーネント間でコンテンツを渡すための slot
メカニズム (紛らわしい let:
と <svelte:fragment>
構文とともに) は、はるかに強力なツールである {#snippet …}
に置き換えられました。
これらの変更に加えて、数え切れないほどの改善があります。ネイティブの TypeScript サポート (プリプロセッサは不要!)、多くのバグ修正、そして全体的なパフォーマンスとスケーラビリティの向上です。
どのようにアップグレードすればよいですか?
現在 Svelte 3 を使用している場合は、まず Svelte 4 に移行してください。
そこから、package.json
を更新して、最新バージョンの svelte
および vite-plugin-svelte
のような補助的な依存関係を使用できます。
コンポーネントをすぐに更新する必要はありません。ほとんどの場合、アプリは (より速く動作する以外は) そのまま動作し続けます。ただし、新しい構文と機能を使用するようにコンポーネントを移行することをお勧めします。npx sv migrate svelte-5
でアプリ全体を移行することもできます。または、VS Code を Svelte 拡張機能で使用している場合は、コマンドパレットで「コンポーネントを Svelte 5 構文に移行」を選択して、一度に 1 つずつコンポーネントを移行できます。
Svelte には、shadcn-svelte、Skeleton、Flowbite Svelte など、アプリケーションで使用できるコンポーネントライブラリの大規模で堅牢なエコシステムがあります。しかし、自分のアプリケーションをアップグレードするために、これらのライブラリが Svelte 5 にアップグレードするのを待つ必要はありません。
最終的には、Svelte 4 の構文のサポートは段階的に廃止されますが、これはしばらく先の話であり、十分な警告があります。
詳細については、包括的な Svelte 5 移行ガイドを参照してください。
新しい CLI
Svelte の新バージョンとともに、新しいコマンドラインインターフェース (CLI) である sv
も用意しました。詳細については、お知らせのブログ記事をご覧ください。
次は?
近い将来、新しい Svelte 5 の機能を活用する新しいバージョンの SvelteKit をリリースする予定です。それまでの間、SvelteKit で Svelte 5 を今日から使用できます。また、npx sv create
は Svelte 5 がインストールされた新しい SvelteKit プロジェクトを作成します。
その後、Svelte 自体に実装したいアイデアがたくさんあります。このリリースは、Svelte 4 の上に構築することが不可能だった多くの改善の基礎であり、私たちは腕まくりして取り組むのが待ちきれません。