Svelte Summit Fall 2023で発表されたSvelte 5の新機能や変更点
.svelte.js/.svelte.tsファイルをコンパイル対象とし、.js/.tsファイルはコンパイル対象外となる
3:51:26~
-
Svelte 4以前のコンパイル対象は .svelte ファイルだけだったが、Runeの導入により .js/.ts ファイルもコンパイル対象としていた
- これによって .svelte ファイルと .js/.ts ファイルで同じコードが書けるようになり、リファクタリングやコピペが楽になってDXが改善された
-
ただし、Runeはコンパイルが必要な独自機能であり、純粋な .js/.ts ではない。そのため、コンパイル対象を .svelte.js/.svelte.ts ファイルに絞ることになった
- 純粋な js/ts ではないよ、と明示することができる
- コンパイラの負担も減る
- 他のフレームワークが独自のRuneを実装する場合の互換性も気にしなくて良くなる
- 末尾は .js/.ts なので、JavaScript や TypeScript の利点は全て得られる
Runeに関する diagnostics の追加
3:52:08~
- $stateでステートを宣言し、そのステートを更新するコードが存在しない場合にメッセージが表示される
-
Svelte 5 Playground
-
count
の下に波線があり、そこをホバーするとメッセージが表示される
-
-
Svelte 5 Playground
- ステートの最新の値を参照できるコードがない場合にメッセージが表示される
-
Svelte 5 Playground
-
count
の下に波線があり、そこをホバーするとメッセージが表示される
-
-
Svelte 5 Playground
playgroundのコードが消えてしまっているようです
追記: 環境を変えたら見られました
class で Rune が使える
3:53:16~
まず前提として、こちらのコードには問題がある
Svelte 5 Playground ※ addTodo
関数を要チェック
- オブジェクトリテラルで getter/setter を使用するとメモリコストがかかるのと、通常のプロパティや通常の関数を呼び出したりするよりも遅くなる
- V8 の誰か、どうか直してほしい。直してくれたら手作りお菓子あげるよ by Richさん
- エルゴノミクス的にも微妙という意見、例えばPrettier に処理させるとワンライナーの
get
set
が展開されてしまう
V8が修正されるのを待っている間に、この2つの問題を解決できないか?
そこでclassの出番。
こんなコードになる。
Svelte 5 Playground
こうするとコード量も減りパフォーマンスも良くなる。
classが嫌いなJavaScripterは多いけれど、このほうが読みやすく、メンテしやすく、デバッグしやすいとのこと。
このIssueがマージされたことでCalssが不要になり、とても簡単に書けるようになりましたね!!
イベントハンドラをpropsとして渡せる
3:54:56~
なぜこの機能が必要になるのか、Svelte 4の良くない点の説明を複数のコード例を用いて丁寧に説明してくれているのですが、時間が足りないのでその部分は割愛します (きっとそのうちドキュメント化されるはず)。
ざっくり言うと、Svelteは当初Web componentsにインスパイアされてイベントハンドラとpropsを明確に区別するアプローチを取っていたが、それが原因でコンポーネントをまたぐイベントのforwardやpropagate、dispatchやdelegationが複雑になっていた、みたいなことです。
コンポーネントに対して、例えばクリックのイベントハンドラを渡すときは on:click
ディレクティブではなく onclick
(セミコロンなし) を使用します。
新たな機能によって改善された、にもかかわらず学ばなければいけなかったコンセプトは減った、というところがさすがです (このためにcreateEventDispatcherや on:
ディレクティブを使用する必要がなくなった)。
既にSvelteを使用している人にとってはアンラーニングが必要になりますが、きっとチュートリアルが作られると思うのでなんとかなるでしょう。
snippetの導入
4:00:59~
インラインコンポーネントのようなものを作るための機能として {#snippet ...}
と {@render}
という機能が追加されます。
この機能も、Svelte 4以前の良くない点を説明しながら、それを少しずつ書き換えながら説明してくれているのでYoutubeを見ていただくほうがわかりやすいと思います。
snippetはただインラインコンポーネントっぽいものを作れるだけでなく、propsとして渡すことができるようになります。渡す方法もいくつかあり、明示的に props として渡すこともできますし、自然なマークアップのように渡すこともできるし、React のような children
も使えるようになります。
ポイントとしては、これによって、slot
が引き起こす読みにくさやわかりにくさも改善されます。
(ちなみにこの slot
も web components からインスパイアされたもので…)
書き方が増えた、と思うかもしれませんが、実際には slot
要素、slot
props、slot
属性、$$slot
、svelte:fragment
を理解する必要がなくなるので、学習コストは減ります(これらの機能はまだ動作しますのでご安心ください)。