小さくて早い?Svelteとは
2019-12-22
azblob://2022/11/11/eyecatch/2019-12-22-light-and-fast-what-is-svelte-000.png

この記事はFIXER Advent Calendar 2019 22日目の記事です。
昨日の記事は工藤さんで「WebRTCの仕組みをざっくり理解する」でした。基礎的な説明から実際に実装されたコードまであってとてもわかりやすかったです。

Svelte

昨今よく使われているVirtualDOMを使用したReactやVueのようなJaveScriptライブラリを見かけますが、Svelteはそれらと違い、.svelteという拡張子のファイルからhtml、css、JavaScriptを吐き出してくれるコンパイラとなっています。

VirtualDOMを使用するフレームワークと比べて何がいいの?

VirtualDOMは変更を比較する際に、VirtualDOMの再構成をし前回との差分を見るという手順を踏む必要があります。それではどうしても無駄な比較が多くなってしまいます。しかし、Svelteはビルド時にアプリケーション内の変更される場所を認識するコンパイラなためVirtualDOMに比べて比較処理は少なくなります。

記法について

ReactやVueとの比較を書こうと思ったのですが公式にちょうど良い例があったので引用させていただきます。

import React, { useState } from 'react';

export default () => {
  const [a, setA] = useState(1);
  const [b, setB] = useState(2);

  function handleChangeA(event) {
    setA(+event.target.value);
  }

  function handleChangeB(event) {
    setB(+event.target.value);
  }

  return (
    <div>
      <input type="number" value={a} onChange={handleChangeA}/>
      <input type="number" value={b} onChange={handleChangeB}/>

      <p>{a} + {b} = {a + b}</p>
    </div>
  );
};
<template>
  <div>
    <input type="number" v-model.number="a">
    <input type="number" v-model.number="b">

    <p>{{a}} + {{b}} = {{a + b}}</p>
  </div>
</template>

<script>
  export default {
    data: function() {
      return {
        a: 1,
        b: 2
      };
    }
  };
</script>
<script>
	let a = 1;
	let b = 2;
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {a + b}</p>

これらのコードは同じ動きをしますが、コード量を比較すると差が一目瞭然ですね。

個人的に好きなところ

  • 上のコードでもわかるのですが、複数のコンポーネントを返すことができる点です。ReactのようにReact.Fragmentで囲ったり、Vueのようにtemplateで加工必要もありません。毎回インデントの階層を増やして囲むのを面倒に思っていた自分からしたらとても嬉しい仕様です。
  • もう一つは、ReduxやVuexのような状態管理が機能として実装されている点です。 新しくパッケージを追加する必要がなく
import { writable } from 'svelte/store';

export const text = writable("hello world");

これだけの記述で宣言する事ができます。

storeの中身を操作したいときも

<script>
	import { text } from './store.js';

	function changeText() {
		text.update(() => "CLICK BUTTON!");
	}
</script>

<button on:click={changeText}>
	Click me
</button>

このようにupdateを呼び出して値を更新するだけです。
あとはstoreの値を使いたいところで以下のように記述するのみです。

	let store_text
  text.subscribe(value => {
		store_text = value;
	});

公式のページに親切に各機能の書き方がわかりやすく見れるようになっていて、サンプルを元にしてその場で書き換えることができるためとても便利です。
https://svelte.dev/examples#hello-world

  • 上の例の種類を見ても分かる通り公式ページがとてもわかりやすくとっつきやすい点も好きでおすすめできる点です。REPLが実装されているため、わざわざ環境を整えずにコードの動作を確かめることができます。

おわり

読んだことや書いたことがある人ならわかると思うのですが、個人的にはRiot.jsVue.jsに似た文法だと感じました。 個人的にどう発展していくか注目していきたいライブラリです。

今回、Svelteの紹介のみの記事になってしまったのですが、次はSvelteで何かを作って記事を書くことを自分への課題にして終わりとします。