Svelteコンポーネント、なぜReact / Vue 上で動いてるの?

この記事は「Eureka Advent Calendar 2020」7日目の記事です。

Hi. webチームのspiceです。

昨年から、Svelteというライブラリの注目度が上がっています。

2020年、Svelte界隈で話題になったBytemdを知っていますか?

Bytemdは、byteDance社が作成したSvelteで書かれたmarkdownエディタライブラリです。

単にSvelteで書かれたことだけでなく、UIフレームワークなしでも使うことができ、React向け/Vue向けのバインディングが用意されていることも注目を浴びました。

この記事では、Bytemdを題材に

  • Svelteで書かれたコンポーネントがReact/Vueで上で動く仕組み

を探ります。

また、これ以降はSvelte,React,Vueの概要をご存知の方向けの内容になります。

それぞれについて知らない方は、公式サイトなどで概要を把握してからこの記事を読むことをおすすめします。

Svelte is compiler.

Svelteで書かれたコードは、ビルド時に全てVanilla JSになります。

ReactやVueで書かれたコンポーネントは、ブラウザのruntime時に、ライブラリを動作させるためのコードが必要になりますが、Svelteの場合はそのようなコードが必要ありません。

例えば、以下のようなSvelteで書かれたコンポーネント、Footer.svelteがあるとします。

Footer.svelte

これがビルドされると、このようなコードにコンパイルされます。

ビルド後のコード(一部)

(SvelteComponent Class, init()などのコードも同時に吐き出されますが、長いので省きました。この記事の最後に付録として載せてあります。)

Svelteのコードは、コンパイルされるとただのVanilla JSで、完結するものになります。開発者が独自に定義したコンポーネントは単なるJavaScriptのClassになっています。

ブラウザ側で受け取るのはこの、自身で処理が完結しているコードなので、JavaScriptが実行可能ならば、他に必要なものはないわけです。

React / Vue can use Javascript.

React / VueはJavascriptのライブラリです。

Javascriptで書かれた他のライブラリと一緒に使うことができます。

前述の通り、Svelteで書かれたコンポーネントがコンパイル後にJavascript のClassになっているので、特に難しいことをせずともReact/Vueの中で使うことができます。

ここで冒頭にふれたBytemdのEditor部分について、React/Vue向けバインディングの中身を見てみます。

React向けバインディング
Vue向けバインディング

どちらも行っていることは同じで、主に2点です。

  • それぞれのコンポーネントライフサイクルに乗っ取ってEditorをインスタンス化
  • propsの値の受け渡しや、Editor内の値の変化を受け取るためのリスナーの登録

やはり、一度コンパイルすればSvelteの都合を特に意識する必要がありません。

細かなパフォーマンスについては調節の余地があるかもしれませんが、Svelteで書いたcomponentはライブラリを問わず使うことができそうです。

おわりに

Bytemdを題材に、SvelteのコンポーネントがReact/Vue上で動く仕組みを探ってみました。

長いエンジニア人生、ライブラリをまたいで使いたいコンポーネントを実装したい時にSvelteが役立つかもしれませんね。

筆者はすでに、ReactとVue上で共通で使いたい状況を思いついているので、そのうち使ってみようと思います。実際に使った時の記事をお楽しみに!

付録

冒頭に登場した、Footer.svelteビルド後のコード全て

Bytemdを見て、自分でもSvelte componentを実験したくて作ったrepository

https://github.com/Spice-Z/svelte-to-x

--

--