こんにちは、”はふぃ”です。

最近のWEBフロントエンド界隈では、Vue.jsReact Angular が主流のフレームワークとなっていると思います。

(私は Vue.js をメインに使っているので、このサイトでは Vue.js のTipsをよく紹介しています)

→ Vue.js に関する記事一覧:https://hafilog.com/category/%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF/vue

そんな三大巨頭のWEBフロントエンド界隈に新しいフレームワークが現れました!

その名も Svelte です。

Svelte は Vue.js に似ているという話を聞いて興味を持ったので、今回は Svelte の特徴や使い方について紹介したいと思います。

Svelteの特徴

  • とにかく軽くて早い
    • 「すらりとした」という意味を持つ名の通り軽量で高速
    • ベンチマークで React の35倍、Vue.js の50倍
  • テンプレートをピュアな JavaScript に変換するコンパイラー
    • テンプレートをコンパイルして、Virtual DOM 形式の UI を持つ Javascript ソースコードを作成する
    • これによって他のフレームワークでは必要なランタイムが不要となるため高速に動作が可能となる
  • テンプレートは html , css , JavaScript を使って書く
    • この辺りが Vue.js に似ていると言われる所以

環境構築

ビルドツールとして webpack を利用するので、npm を使ってインストールします(npm の準備ができていない人は $ npm init で作成しておいてください)。

$ npm install --save-dev webpack webpack-cli webpack-dev-server

続いて webpack の設定ファイルを作成します。

< webpack.config.js >

const path = require('path'
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: { main: './src/index.js' },
  plugins: [ new HtmlWebpackPlugin() ]
}

html-webpack-plugin が必要なのでインストール

$ npm install --save-dev html-webpack-plugin

起動コマンドを package.json に追加します。

< package.json >

"scripts": {
  "start": "webpack-dev-server --mode development --hot --open --content-base public"
}

ここでようやく Svelte をインストールしていきます。

$ npm install --save-dev svelte svelte-loader

webpack にsvelte-loaderの設定を行う必要があるので、 webpack.config.js に設定を追加します。

< webpack.config.js >

module.exports = {

…

  module: {
    rules: [{
      test: /\.html$/,
      include: path.resolve(__dirname, './src'),
      use: [{ loader: 'svelte-loader' }]
    }]
  }
}

環境はこれでできたはずなので、サンプルコードを作成して試してみましょう。

< src/main.js >

import App from './App.html'

window.app = new App({
  target: document.body
})

< src/App.svelte >

<div>{ message }</div>

<script>
  const message = 'Hello World!'
</script>

Hello World!が画面に表示されたら成功です!

Svelteの使い方

ここからは Vue.js の書き方と比較しながら Svelte を使うとどのように書けるかを説明していきたいと思います。

Data

< vueSample.vue >

<template>
  <div>
    {{ sum }}
  </div>
</template>

<script>
export default {
  data () {
    const num1 = 1
    const num2 = 2
    return {
      sum: num1 + num2
    }
  }
}
</script>

< svelteSample.html >

<div>
  { sum }
</div>

<script>
  const num1 = 1
  const num2 = 2
  const sum = num1 + num2
</script>

Computed

Svelte で Computed を表現する際には変数を定義する際に $: を先頭につけます。

現在時刻がリアルタイムに更新されていくコードをそれぞれで表現すると以下のようになります。

< vueSample.vue >

<template>
  <div>
    {{ time }}
  </div>
</template>

<script>
export default {
  data () {
    return {
      date: new Date()
    }
  },
  computed: {
    time () {
      return `${this.date.getHours()}:${this.date.getMinutes()}:${this.date.getSeconds()}`
    }
  },
  mounted () {
    setInterval(() => {
      this.date = new Date()
    }, 1000)
  }
}
</script>

< svelteSample.html >

<div>
  { time }
</div>

<script>
  let date = new Date()
  setInterval(() => {
    date = new Date()
  }, 1000)
  $: time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
</script>

Methods

メソッドは関数なので Svelte では function() を使って定義するだけです。(サンプルではアロー関数を使って表現しています)

< vueSample.vue >

<template>
  <div>
    {{ getUpperCaseStr('Hello World!') }}
  </div>
</template>

<script>
export default {
  methods: {
    getUpperCaseStr (str) {
      return str.toUpperCase()
    }
  }
}
</script>

< svelteSample.html >

<div>
  { getUpperCaseStr('Hello World!') }
</div>

<script>
  const getUpperCaseStr = (str) => str.toUpperCase()
</script>

Props

< vueSampleParent.vue >

<template>
  <div>
    <child-component :message="message" />
  </div>
</template>

<script>
import childComponent from './vueSampleChild.vue'

export default {
  components: {
    childComponent
  },
  data () {
    return {
      message: 'this is props sample!'
    }
  }
}
</script>

< vueSampleChild.vue >

<template>
  <div>
    {{ message }}
  </div>
</template>

<script>
export default {
  props: {
    message: { type: String, default: '' }
  }
}
</script>

引数を子要素と受け渡すには export を変数名の先頭に記述します。

< svelteSampleParent.html >

<div>
  <ChildComponent message={ message } />
</div>

<script>
  import ChildComponent from './svelteSampleChild.html'

  const message = 'this is props sample!'
</script>

< svelteSampleChild.html >

<div>
  { message }
</div>

<script>
  export let message = ''
</script>

Model

< vueSample.vue >

<template>
  <div>
    <input v-model="inputValue">
    <p>
      input value is "{{ inputValue }}"
    </p>
  </div>
</template>

<script>
export default {
  data () {
    return {
      inputValue: ''
    }
  }
}
</script>

< svelteSample.html >

<div>
  <input bind:value="{ inputValue }">
  <p>
    input value is "{ inputValue }"
  </p>
</div>

<script>
  let inputValue = ''
</script>

まとめ

こんな感じで Vue.js に似た書き方でコードを書くことができ、50倍早く動作するようなので興味がある人は試してみるといいかもしれないですね。

投稿者: はふぃ

若手のWEBフロントエンジニア。最近はバレーボールにハマってます!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA