KINTO Tech Blog
Development

Svelteと他JSフレームワークの比較 - Svelte不定期連載-01

Yusuke Ikeda
Yusuke Ikeda
Cover Image for Svelteと他JSフレームワークの比較 - Svelte不定期連載-01

こんにちは(こんばんは)、始まりました。
Svelte不定期連載その1です。

前回はざっくりとSvelteKitを動かすまで、を書いてみました。
(SvelteKitのメジャーアップデートに伴って内容もアップデートしましたのでよかったら一読ください)

今回は、Write less codeをコンセプトとしたSvelteと他のJSフレームワークで、それぞれ書き方にどんな特徴があるのかを比較してみます。

Svelte / React / Vue.js

仮想DOMであるReactとVue.js、仮装DOMを持たないSvelteではありますが、比較対象としてはよくあげられるので改めて比較します。
※Svelte(v3系) / React(v18系) / Vue.js(v3系) で行います。

Fetch&ループ処理

Fetchとループ処理はセットで書かれることが多いので、まとめて記述してそれぞれを比較してみます。

Svelte

まずはSvelteから。
Svelteは独自の構文がありますね、
await/ block構文があるのですっきり書けるのが特徴です。

Fetch on Svelte
<script>    
  const fetchItems = async function() {
    const items = await fetch('URL');
    return await items.json();
  }
</script>

{#await fetchItems()}
  <p>Loading</p>
{:then items}
  {#each items as item}
    <p>{item.name}</p>
  {/each}
{:catch error}
<p>{error.message}</p>
{/await}

React

Svelteと比べるとコードの行数が増えました。
とはいえ、本来であれば分割なりをするので、このまま書くことは滅多にないでしょう。
useStateではじめに定義するあたりがReactらしいのでしょうか。

Fetch on React
function FetchComponent() {
  const [error, setError] = useState(null)
  const [isLoaded, setIsLoaded] = useState(false)
  const [items, setItems] = useState([])

  useEffect(() => {
    fetch('URL')
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result)
        },
        (error) => {
          setIsLoaded(true);
          setError(error)
        }
      )
  }, [])

  if (!isLoaded) {
    return <div>Error: {error.message}</div>;
  } else if (!isLoaded) {
    return <div>Loading...</div>;
  } else {
    return (
      <ul>
        {items.map(item => (
          <li key={item.id}>
            {item.name}
          </li>
        ))}
      </ul>
    );
  }
}

Vue.js

次はVue3、
2系と比べるとReactに書き心地が似てきた感覚があります。

Fetch on Vue
<script setup>
import { ref } from 'vue'

const items = ref(null)
const error = ref(null)

fetch('URL')
  .then((res) => res.json())
  .then((json) => (items.value = json))
  .catch((err) => (error.value = err))
</script>

<template>
  <div v-if="error">{{ error.message }}</div>
  <div v-else-if="items">
	  <ul v-for="(item,index) in items">
		  <li>Number:{{index+1}} Name:{{item.name}}</li>
	  </ul>
  </div>
  <div v-else>Loading</div>
</template>

Reactive

これもコンポーネントを使い回す現代のフロントエンドで必須の仕組みですね。

Svelte

Svelteでは接頭辞に$:をつけることでリアクティブになります。
$:をつけない限り依存する値が変更されても実行されません。
他のフレームワークになれているとこのあたりは最初面食らうかもしれません。
いざ使うと明示的だなぁと感動します。

Reactive on Svelte
$: foo = false

React

細かい説明を省きますが、ReactではuseStateで定義するのが一般的です。
Svelteと比較すると、useState$: と同等の役割でしょうか。

Reactive on React
import {useState} from 'react'
const [foo] = useState(false)

Vue.js

Vueの場合はreactiveで生成すると変更されます。

Reactive on Vue
<script setup>
import { reactive, computed } from 'vue'

const state = reactive({
  count: 0
})

const increment = () => {
  state.count++
}
</script>

propsについて

今回は基礎である文字列を受け渡す方法で比較してみます。
三者三様かと思いきや、ほとんど同じような書き心地になってきました。

Svelte

ChildComponent.svelte
<script>
  export let name
</script>

<p>Hello, I'm :{name}</p>
ParentComponent.svelte
<script>
import ChildComponent from './ChildComponent.svelte'
</script>

<ChildComponent name="Svelte" />

React

ChildComponent.jsx
const ChildComponent = (props) => {
  return <h1>Hello, I'm :{props.name}</h1>;
}
export default ChildComponent;
ParentComponent.jsx
import ChildComponent from './ChildComponent.jsx'

function App() {
  return (
    <ChildComponent name="React" />
  );
}

export default App

Vue.js

ChildComponent.vue

<template>
	<p>Hello, I'm {{name}}</p>
</template>

export default {
  props: {
    name: String,
  }
}
ParentComponent.vue

<script>
import ChildComponent from './ChildComponent.vue'
</script>
<template>
<ChildComponent name="Vue" />
</template>

子コンポーネントをimportして値を渡す。
どれもわかりやすい書き方でした。

総評

短いですがSvelteと、React、Vue.jsを比較してみましたがいかがでしたでしょうか。

それぞれ良さがある中で、Write less codeをテーマにしたSvelte。
とっつきやすさがやはり際立っている印象があります。

よきSvelteライフをお過ごしください。

そして初めての方はSvelteを是非書いてみてください、とても楽しいフレームワークです。

Facebook

関連記事 | Related Posts

We are hiring!

【フロントエンドエンジニア(DX等)】オウンドメディア&インキュベート開発G/東京・大阪

オウンドメディア&インキュベート開発グループについてKINTO ONE売上拡大を目的とした、全国約3,600店舗の販売店に対するテクノロジーを用いたソリューション提案のためのシステム開発と、『 KINTOマガジン 』『 モビリティマーケット 』『 Prism Japan 』など、オウンドメディアのクリエイティブ制作も手掛けています。

【フロントエンドエンジニア】新車サブスク開発G/東京・大阪

新車サブスク開発グループについてTOYOTAのクルマのサブスクリプションサービスである『 KINTO ONE 』のWebサイトの開発、運用をしています。​業務内容トヨタグループの金融、モビリティサービスの内製開発組織である同社にて、自社サービスである、TOYOTAのクルマのサブスクリプションサービス『KINTO ONE』のWebサイトの開発、運用を行っていただきます。