フロントエンド連載の6記事目です。
今年のゴールデンウィーク(STAY HOME週間)に最近話題のSvelteに入門したので紹介を書きます。
Svelteとはなんですか?
公式のサイトはこちらです。有志の方々が日本語翻訳のサイトを作ってくれています。たいへんありがとうございます!
Svelteは主にブラウザ上で動作するユーザーインタフェースを作るフレームワークで、ReactやVue.jsの対抗馬的な存在です。
特徴とReactやVue.jsなどほかとの違い
公式サイトでも、コーディングする際のコード量が少ないという特徴があげられています。
詳しくはこちらのブログに書かれています。コードが多ければ作業時間とバグが増えてしまうため、コードが減らすことはこれらの問題を減らすことができるというようなことが書いてありました。またブログには具体的なコードで量の差について書いていますのでぜひ見てみてください。
Svelteは主にコンパイラであり、ReactやVueと比べるとSvelteはランタイムをほとんど提供しません。これによって構築するアプリケーションの特性によってはリソースサイズを最小に抑えられる可能性があります。
さらに、Svelteのコンパイラは、Lintのようなコードチェックを行います。基本的なところだと、未使用変数や未定義変数の使用を警告してくれたりしますが、おもしろいところだと未使用のCSSセレクタを検出して警告してくれたり、アクセシビリティ(A11Y)的に問題のあるHTMLを検出して警告してくれます。
アクセシビリティのチェックは、ReactやVueでもESLintプラグインなどを使用すればチェックできますが、Svelteはこれを標準で行うというところが先進的で良い取り組みだと思います。
そのほか、公式サイトであげられている特徴として、仮想DOMなし(No virtual DOM)、真のリアクティブ(Truly reactive)があります。
Svelteの開発元
SvelteはRich Harrisさんを中心としたチームによって作成されています。Rich HarrisさんはRollupの作者としても有名です。あとホーム・アローンという映画に出てくる人らしいです(嘘です。冗談です)。
Svelteは、ReactやAngularのように企業がバックにいるわけではありませんが、Rich Harrisさんが現在属しているNew York TimesではSvelteを積極的に使用しているようです。
Svelteの近況
毎年年末ぐらいに発表される The State of JavaScript の2019年にフレームワークランキングでSvelteが初登場し上位に食い込みました。そして2020年には1位となりました。世界的にはかなり注目と期待が集まっているということだと思います。
日本の話だと、2021年4月24日に発売されたWEB+DB PRESS Vol.122 でSvelteの記事が載ってました。日本でも注目が集まっているということでしょうか?
Svelteに入門する
Svelteに入門するために開発環境を整える必要はありません。Svelteは公式のREPLというブラウザ上で簡単に試すことができるしくみがあります。
そして、Svelteに入門するためのチュートリアルも説明とともにREPL上で試しながら学べるように作られています。
入門するために環境を用意するのは地味に面倒くさいので、時間とブラウザがあれば簡単入門できるこのしくみはとても便利です。
もしローカルで動かして試したくなった場合は、REPLページの上の方にダウンロードボタンがあるので、そこからダウンロードしたzipファイルを解凍してそのディレクトリでnpm i && npm run devするだけで同じものをローカルで試すことができます。
さらに、REPLで動作するサンプルコードが次のリンクにたくさん用意されています。
自分が触り始めたい状態のサンプルを見つけたらREPL→を押してダウンロードボタンからダウンロードするだけで簡単に同じ状態をローカルに構築できます。とても簡単です!
Svelteの基本的な構文
いくつかのSvelte構文を紹介しますが、この記事では詳細を書かないので少しでも興味が湧いたらチュートリアルを見てもらうとよいと思います。
Svelteでは.svelteという拡張子のファイルを使用します。これらをSvelteでコンパイルすることによってWebアプリケーションを構築していくことになります。.svelteファイルはVueの単一ファイルコンポーネントと同じで、HTML、JavaScript、CSSを記述して1つのUIコンポーネントを作成します。
たとえば次のように書きます。
<script> |
動作させると次のように表示されます(REPLにソースコードを貼り付けるだけで簡単に試せます!)
それではいくつかの構文について紹介していきます。
バインディング・テキスト挿入
中括弧{}を使用してテンプレートにテキストを埋め込むことができます。
次は簡単な例です。
<script> |
Svelteは<script>に書かれたJavaScriptのトップレベルで宣言された変数や関数をテンプレートで使用できます。上記の例ではname変数を宣言し、テンプレートで{name}と書くことでこの部分にname変数の値がテキストとして表示されます。
上記のコードは実際には次のHTMLが表示されます。
<h1>Hello world!</h1> |
中括弧{}は属性にも記述できます。
<script> |
このソースコードは<img>のsrc属性にsrc変数の値が与えられ、alt属性にname + " dances."が与えられます。
src="{src}"部分はさらに省略できます。属性に与えるデータが1つの変数(および式)の場合は、引用符を省略できます。つまり、src={src}と書くことができます。さらに、属性名と与える変数が同じ場合{src}と書くだけで同じことができます。
<script> |
(引用符の省略や省略記法はこの記事では意図的に使用しないことがあります。このブログはSvelteのシンタックスハイライトが効かないため見やすさのためHTMLシンタックスを使用しており、引用符を省略するとHTMLシンタックスが壊れ、記述が見にくくなるためです。ご了承ください)
双方向データバインディングをするにはbind:属性名のような記述をします。
次の例は<input>に入力した値がname変数に与えられる例です。
<script> |
bind:にも条件によって省略記法がありますが割愛します。気になる方はチュートリアルを見てみてください。
参考:
- https://svelte.jp/tutorial/adding-data
- https://svelte.jp/tutorial/dynamic-attributes
- https://svelte.jp/tutorial/text-inputs
イベントハンドラ
イベントハンドラを登録するにはon:イベント名のような記述をします。次の例は<button>のクリックイベントにhandleClick関数を登録する例です。
<script> |
Svelteにはbind:やon:のように:で区切った属性を使用する記述方法(ディレクティブと呼ばれます)がいろいろとあります。
参考:
ifブロック
テンプレートで、条件によって変化させたい記述をするには{#if}ブロックを使用します。
<script> |
Svelteにはほかにも{#each}ブロックを使用した反復表示や{#await}ブロックを使用したPromiseの状態別の表示などがあります。
参考:
コンポーネントを使用
別の.svelteで作成したコンポーネントを使用するにはimportしてタグのように記述するだけです。
<script> |
リアクティブ
テンプレートが変数の値の変化によって変化するのはこれまでの結果でもわかったと思いますが、スクリプトでも特殊な記述によって、変数の変化に応じて処理したり、変数の結果に応じて値の変わる変数を宣言したりできます。
この記述には$:というような記述をします。
次の例は変数の結果に応じて値の変わる変数を宣言する例です。$: 変数のような記述をします。doubledには常にcountの2倍の値が格納されます。Vueの算出プロパティと似ています。
<script> |
変数の変化に応じて処理を行いたい場合は$: ステートメントのような記述をします。$の後に処理したいステートメントを記述すると、ステートメントで使用した変数が変化したタイミングで処理されます。VueのwatchEffectに似ています。
次の例はcount変数の変化に応じて処理を実行する例です。10回ボタンをクリックするとメッセージが表示されます。
<script> |
if文はステートメントなので$:の後の{}は書かなくても同じです。
$: if (count >= 10) { |
参考:
SvelteのライフサイクルフックとSvelteの機能を使用した構文
今まで紹介した記述はsvelteをライブラリとしてインポートすることはありませんでした。次はsvelteをライブラリとしてインポートして使用する機能や構文を紹介します。
ライフサイクルフック
コンポーネントが最初にDOMとしてレンダリングされた後(マウント)に何かの処理をしたり、コンポーネントが破棄されたときに何かの処理をしたい時は、ライフサイクルフックを使用します。
次の例はマウント時に処理をする例です。'svelte'からimportしたonMountを使用します。マウントされたタイミングでメッセージが表示されます。
<script> |
ライフサイクルフックにはonMount、beforeUpdate、afterUpdate、onDestroyがあります。
参考:
ストア
Svelteはストアという機能を持っています。これは簡単に言えば状態管理の機能です。Vueでいうところのrefオブジェクトなんかが機能的には近いのではないでしょうか?
Svelteは変数などの値の変更がリアクティブに反応してDOMなどが更新されることは今までの説明でなんとなくわかると思いますが、今までの方法では.svelteファイルの外で管理されている値(状態)には反応できません。値(状態)を複数のコンポーネントで共有したりする場合はSvelteのストアの機能を使用します。
ストアを作るには'svelte/store'からインポートできる関数を使用します。
詳細は割愛しますが、次のコードではcountというストアを作成しました。
/* stores.js */ |
.svelteでストアを使用する際はストアの名前の頭に$をつけた変数名を使用します($を使用しない方法もありますが便利なのは$を使用する方法です)。
次の例ではボタンクリックによってcountストアを1増やすコンポーネントです。実際にcountストアを1増やしているのは$count++と書いた部分です。
<!-- Incrementer.svelte --> |
ストアの値を参照する場合も同じように$をつけます。次の例はテンプレート部分で$countと記述することでcountストアの値を参照しています。実際に動かしてみるとIncrementer.svelteでの値の更新に反応して、表示が変化することを確認できます。
<!-- App.svelte --> |
参考:
アニメーション
Svelteはtransition:name、in:name、out:nameやanimate:nameのディレクティブを使用してさまざまなアニメーションを実現できます。
おそらく説明するよりは実物を見てもらったほうがよいと思うのでこれとかサンプルをぜひ見てみてください。おもしろいアニメーションを作るためだけにSvelteを学ぶのも良いかもと思うぐらい、Svelteだけでいろいろなアニメーションが作れます。
チュートリアルはこのあたりから始まります。
構文や機能についての紹介はこのあたりで終わりにしますが、まだまだ紹介していない便利な機能がたくさんあります。さらに詳細を知りたい方はチュートリアルを覗いてみてください。
Svelteのコミュニティ
海外ではSvelte SocietyというSvelteのコミュニティがあります。
このサイトの中にはSvelteで使えるライブラリがたくさん載っていたり、Svelteとこれを組み合わせるにはどうしたら良いか?などのレシピ集があったりと、Svelteを本格的に始めるには重要な情報が多くあるので、必ずチェックすべきサイトです。このコミュニティのチャットはDiscordにあります。もしドキュメントを読んでもわからないような質問があれば、投稿してみるともしかしたら誰かが答えてくれるかもしれません。
日本にも「Svelte日本」というSvelteのコミュニティがあります。Svelte日本 はこれまでリンク先として紹介してきた日本語翻訳にも取り組んでくれています。こちらのチャットもDiscordにあります。Svelte日本 のDiscordには、困ったときの「help」チャンネルもありますが、週3回Svelteに関するクイズが出題される「svelteクイズ」という楽しく学べるチャンネルがあったりします(ただし先週から休止中。過去の問題を見ることはできます)。
参考:
Svelteのイベント
Svelte Societyにイベントがまとめられているページがあります。
最近行われたSvelte Summit Spring 2021と前回のSvelte Summit 2020についてはまとめ記事を書いてくださった方がいますのでリンクを紹介しておきます。
感想
REPLのおかげか、とにかく入門するのが楽でした。ちょっと時間ある時にブラウザで開いてコード書いて動かせるので本当に楽です。
Svelteの構文についてはコードをスマートに書けるよう設計されているのがよくわかりました。Svelteを使えばコードがスッキリして気分良くコーディングできそうです。
ライブラリやツールなどはほかの有名どころフレームワークと比べるとまだ成熟していないようにも見えますが、主要なツールのサポートはおおむねそろっている印象を受けました。
公式リポジトリでエディタのサポートやPrettierプラグインがメンテナンスされていたりするので、もし何か足りないことが見つかってもSvelteコミュニティと協力できればすぐに実現されそうな期待があります。