

もずくです。
タイトルは気にしないでください。
2019年にブレイクしたSvelteというJSフレームワークの話をしようとして、前回はJSフレームワークとは…みたいなところで終わってしまいました。
今回はこの続きです。
JavaScript界というかウェブフロントエンド界は本当に目まぐるしくトレンドが入れ替わっていくのですが、ここ数年はJSフレームワークの3トップであったReact・Vue.js・Angularの間に突然割って入ってきたのがSvelteです。
Svelte自体はもう少し前からあったのですが、バージョン3になって大きく変化し、一気に注目を集めることになったようです。私もSvelteのことを知ったのは1ヶ月ほど前なのですが、そのシンプルでわかりやすい構文に惚れ込んでしまいました。
2020年、SvelteがVue.jsの座を脅かす存在になるのかどうか、いまから楽しみです。
では早速、Vue.jsとのコードの比較に入ってきたいと思います。
なお、2019年までのJSフレームワークのデファクトスタンダードはReactなのですが(おそらく数年はトップを維持すると思いますが)、プログラミング初心者がウェブアプリを作るくらいの内容であればVue.jsのほうがコード量が少なく書けます。
ので、ここではVue.jsのみを比較対象とします(ま、私がReact書けないだけなのですが(Facebookは嫌いなのです))。
前回の記事でJavaScriptと比較していたVue.jsのコード三つをSvelteで書いてみたいと思います。
自分でも打ち込んでみたいという人は、Vue.jsはJSFiddle、SvelteはSvelte REPLを使ってみてください。
まずは配列の内容をリスト表示するアプリ(と呼べるのか?)です。

【Vue.jsの場合】
以下、同じ場所にHTMLとJavaScriptを書いています。JSFiddleでもHTMLの欄に以下のように<script>タグでJavaScriptを書いても動くようです。
<div id="app">
<ul>
<li v-for="coin in coins">{{coin}}</li>
</ul>
</div><script>
new Vue({
el: "#app",
data: {
coins: ['BTC', 'ETH', 'MONA', 'ALIS']
}
});
</script>
これでもJavaScriptと比べると十分に短くて簡潔だったわけですが…
【Svelteの場合】
<script>
const coins = ['BTC', 'ETH', 'MONA', 'ALIS'];
</script>
<ul>
{#each coins as coin}
<li>{coin}</li>
{/each}
</ul>
Svelteではこうなります。
まず、大きく異なるのがVue.jsにある「new Vue({」から始まるオブジェクトの記述がSvelteにはないことです。Vue.jsでは、HTML側で使用したい変数はVueオブジェクトの中のdataプロパティとして定義する必要があります。
一方、Svelteでは、HTML側で使われる変数や定数(coins)は<script>タグの中で単純に定義されているだけです。特別な記法を使わなくとも、スクリプト側の変数/定数はすべてHTML側で使えます。
次に、Vue.jsでは<li>内のカスタム属性(v-forディレクティブと呼ばれます)でfor文を表現していましたが、Svelteは {#each ...} というHTMLのタグとは独立した構文を使います。
そのせいで行数増えてるやん…と思うかもしれませんが、複数行の繰り返しをするときはこちらのほうが自然であるように私は思います。
例えばVue.jsの場合、<li>を複数行繰り返そうとすると、繰り返し部分を囲う何かしらのタグを付け加えないといけません。適当なものがないときは<template>タグを使用します。
<ul>
<template v-for="coin in coins">
<li>{{coin}}</li>
<li>{{coin}}</li>
</template>
</ul>
Svelteのほうはそういった不自然さはなく、繰り返しが1行の場合と同じです。
<ul>
{#each coins as coin}
<li>{coin}</li>
<li>{coin}</li>
{/each}
</ul>
あとは、細かい話ですが、Vue.jsの場合、JavaScript側の変数をHTML(のテキストコンテント)で使用する場合には {{coin}} というように「{」を二重にして囲いますが、Svelteは {coin} と一重でシンプルです。
さらに、繰り返しの each 構文も { } で囲われており、一貫性があります。
ちなみに条件分岐の場合も同様で、Vue.jsは <tag v-if="条件式"> というようにタグの中に書き、Svelteは {#if 条件文} と { } の中に書きます。一貫性!
さて、次はコインのリストに新しいコインを追加できるようにするコードを見てみましょう。

【Vue.jsの場合】
<div id="app">
<ul>
<li v-for="coin in coins">{{coin}}</li>
</ul>
<p>
<input v-model="newCoin">
<button v-on:click="add">追加</button>
</p>
</div>
<script>
new Vue({
el: "#app",
data: {
coins: ['BTC', 'ETH', 'MONA', 'ALIS'],
newCoin: ''
},
methods: {
add: function() {
this.coins.push(this.newCoin);
this.newCoin = '';
}
}
});
</script>
【Svelteの場合】
<script>
const coins = ['BTC', 'ETH', 'MONA', 'ALIS'];
let newCoin = '';
function add() {
coins[coins.length] = newCoin;
newCoin = '';
}
</script>
<ul>
{#each coins as coin}
<li>{coin}</li>
{/each}
</ul>
<p>
<input bind:value={newCoin}>
<button on:click={add}>追加</button>
</p>
こちらはVue.jsとよく似ています。
まず、Vue.jsでは「v-model="newCoin"」となっているところが、Svelteでは「bind:value={newCoin}」となっています。
Vueに比べるとSvelteのほうがやや表現が複雑に見えるかもしれませんが、実はVueも入力フォーム以外では「v-bind:style="myStyle"」のように「v-bind」という表現を使います。その点、Svelteは(例えば)style属性の場合でも「bind:style={myStyle}」ですので統一感があります。統一感!
また、Vue.jsではVueオブジェクトのmethodプロパティの中で add という関数(メソッド)を定義していますが、Svelteはスクリプトの中で普通に定義した関数を使用しています。この点は最初の例のdataプロパティ/変数の関係と同じですね。
あと、細かい話ですが、Vue.jsの場合、HTML側の属性値とJavaScript側の変数(や関数)を紐付けるときに「v-model="newCoin"」というように " " を使います。HTMLの普通の属性値の表記でも「<p class="hoge">」などというように " " を使うので、JavaScript側の変数/関数を指しているのか単なるHTMLの属性値なのか区別しにくいです。
その点、Svelteは「<input bind:value={newCoin}>」というように { } を使いますから、HTMLの属性値とは明らかに区別できます。微妙な違いですが、Vue.jsを文理融合系の大学で教えるときにここでよく混乱しているので、プログラミング初心者には意外と重要なポイントかもしれません。
☕ 前回の記事のVue.jsのサンプルコードでは <button @click="add"> じゃなかったっけ…?と思った人、鋭いです…というか、記憶力が良すぎて怖いです。Vue.jsは、v-onとv-bindに対して略記法があり、それぞれ「@」「:」だけで表記できます。前回の記事では素のJavaScriptに対するJSフレームワークの利点をアピールしたかったので略記法で書きました。
最後に、入力値がリアルタイムに反映されるやつ(語彙力)です。

【Vue.jsの場合】
<div id="app">
<p><input v-model="alis"> ALIS</p>
<p>{{alis * 3.64}} 円</p>
</div>
<script>
new Vue({
el: "#app",
data: {
alis: 0
}
});
</script>
まあ、シンプルですね。
【Svelteの場合】
<script>
let alis = 0;
</script>
<p><input bind:value={alis}> ALIS</p>
<p>{alis * 3.64} 円</p>
まあ、シンプルです。Vueオブジェクトがない分、本当にシンプルですね。
こちらも当然、リアルタイムに入力値が反映されます。
以上のように、Reactに比べると記述がシンプルなVue.jsですら冗長に見えてしまうほどのシンプルさがSvelteにはあります。さすが、svelte(=すらっとした)ですね。
私は、Vue.jsもSvelteも本格的なウェブアプリ開発のために触ったことはないので、お遊びの範囲での比較になりますが、この記事で紹介していない部分でもSvelteは全体的にVue.jsに比べてシンプルです。
というのも当然で、Vue.js(やReact)はHTMLとJavaScriptそのものであるのに対して、Svelteは一見HTMLとJavaScriptに見えますが独自言語です。Svelteのコードから「コンパイル」という操作を通してJavaScriptに変換するので、オリジナルのHTMLやJavaScriptの制約にとらわれません。
一方で、Vue.jsは「コンパイル(あるいはデプロイ)」という操作なしでも実行できます。Vue.jsのスクリプトを記述する直前に以下の1行を入れます。
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
例えば、以下のコードを「index.html」という名前で保存してダブルクリックしてみてください。アプリ(といえるのか?)がブラウザですぐに立ち上がるはずです。
<!doctype html>
<div id="app">
<p><input v-model="alis"> ALIS</p>
<p>{{alis * 3.64}} 円</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
alis: 0
}
});
</script>
対して、Svelteにはこの手軽さはありません。サーバサイドで動作するので、手元のPCのブラウザでHTMLファイルを開くだけ…というお手軽さはないのです。
公式にある一番簡単な方法でも、
自分のPCにnode.js(とnpm)をインストールして、
先ほどのSvelte REPLでコードを書いて、ZIPファイルをダウンロード&解凍して、
ターミナルなりコマンドプロンプトから
% cd ZIPファイルの解凍先へのパス
% npm install
% npm run build
を実行して、以下のコマンドで自分のPCにnowをインストールして(2回目以降は不要)、
% npm install -g now
% now login
…とするとメールアドレスを指定するとメールが届くのでVerifyボタンを押して、
次のようにpublicフォルダに移動してnowでデプロイすれば、
% cd public
% now → ここでセットアップ&デプロイするか訊かれるのでYes
% now deploy --name アプリ名
例えば以下のようにインターネット上に公開されて晴れて実行結果が見られます。
☕ 普通はいきなりインターネット上に公開せず、自分のPCで実行しながら修正を加えると思います。上記の「npm run build」のところで「npm run dev」と打ち、ブラウザで「localhost:5000」にアクセスすればアプリが表示されます。修正するファイルは「src/App.svelte」です。
ということで、最後の最後で全然初心者向けじゃなくなるSvelteさんでした😜










