Mithrilによるシングルページアプリケーション開発 🚀 環境構築 ~ 基本動作編
はじめまして。
manebi開発クラ部の中の人、フロントエンド担当のKです。
シングルページアプリケーションを作りたい!
そう思い立った場合、どこから学習を始めるべきでしょうか。
デファクトスタンダードになりつつあるReact?日本語情報の多いVue?新進気鋭のSvelte?
これらは素晴らしいソリューションですが、いずれも相応の学習コストがかかります。
語弊を恐れず大雑把に表現すると、Reactは動作原理はシンプルですが最適な実装が難しく、VueやSvelteは実装は簡単ですが処理が抽象化されているために動作原理を厳密に理解しようとすると難しくなります。
基本的なJavaScriptの知識だけでサクッと実装できるフレームワークってないの?と感じた方には、ぜひMithrilを試してほしいです。マイナーなフレームワークですので、実装例も交えて紹介できればと思います。
Mithrilって何?
前述の通り、Mithrilはシングルページアプリケーションを構築するためのフレームワークです。
ユーザーフレンドリーな公式ドキュメントもあるので是非一読して頂きたいですが、他のフレームワークと明確に違うところはJavaScriptのみで記述できることを重視している点です。
ReactのJSX、VueのSFCといった、別プロセスで変換が必要なファイルは不要で、ここからもMithrilのシンプルさが伺えます。
環境構築
Mithrilは純粋なJavaScriptのみで記述できるため、HTMLファイルだけで実装例を紹介することも可能ですが、公式のGetting Startedと内容がかぶってしまうため、この記事ではnode.jsを使用したもう少しだけ本格的な環境構築から始めていきます。node.jsはインストールされている前提で進めますので、インストールされていない場合は公式サイトを参考に準備をお願いします。
シングルページアプリケーションではパフォーマンスの観点から個々のJavaScriptファイルを最終的に一つにまとめ上げる必要があります。そのためのツールをバンドラーと呼んだりしますが、この記事では最近勢いのあるViteを利用します。
まずはプロジェクトを作成します。適当なディレクトリを作成し、ディレクトリ配下で以下のコマンドを実行します。
npm init -y
続いてMithrilをインストールします。
npm install mithril
続いてViteをインストールします。
npm install --save-dev vite
動作確認
最初にエントリーポイントとなるHTMLファイルを作成していきます。
プロジェクトディレクトリ直下にindex.htmlを作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mithril SPA</title>
<script type="module" src="/src/main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
続いて、JavaScript側のメインファイルを作成します。プロジェクトディレクトリ直下にsrcディレクトリを作成し、src配下にmain.jsを作成します。
import m from 'mithril'
class Home {
view () {
return m('main', [
m('h1', 'Mithril SPA')
])
}
}
const element = document.getElementById('app')
m.mount(element, Home)
次に、ビルド用のスクリプトを追加します。package.jsonのscriptsにdevという名前で追加していきます。
"scripts": {
"dev": "vite",
"test": "echo \"Error: no test specified\" && exit 1"
},
動作確認する準備が整ったので、npmスクリプトを実行しましょう。
npm run dev
この状態で http://localhost:5173/ にアクセスすると Mithril SPA と表示されます。
ページを動かしてみる
現段階では静的な値が表示されているだけなので、ボタンクリックで数字が増えていくカウンター機能を実装してみます。
main.jsを以下のように修正します。
import m from 'mithril'
class Home {
count = 0
view () {
const countUp = () => {
this.count += 1
}
return m('main', [
m('h1', 'Mithril SPA'),
m('div', [
m('h2', 'カウンター'),
m('h3', this.count),
m('button', { onclick: countUp }, 'カウントアップ')
])
])
}
}
const element = document.getElementById('app')
m.mount(element, Home)
カウントアップボタンを押すと、カウントが増えるはずです。
差分としては
・クラスにcountプロパティを追加した
・countプロパティを更新するcountUp関数を定義し、ボタンのonclickイベントに紐づけた
これだけなので、直感に即しており理解しやすいのではないでしょうか?
コンポーネントにしてみる
繰り返し使うUI部品は共通部品として切り出しておくと便利です。その際に状態を内包した部品として定義することができ、これをコンポーネントと呼びます。(他のフレームワークでもこのように呼ばれることが多いです)
カウンター機能が共通部品となるかはさておき、学習目的でカウンターコンポーネントを作成してみましょう。
srcディレクトリ配下にcomponentsディレクトリを作成し、Counter.jsを作成します。
import m from 'mithril'
export default class Counter {
count = 0
view () {
const countUp = () => {
this.count += 1
}
return m('div', [
m('h2', 'カウンター'),
m('h3', this.count),
m('button', { onclick: countUp }, 'カウントアップ')
])
}
}
main.jsを次のように更新します。
import m from 'mithril'
import Counter from './components/Counter'
class Home {
view () {
return m('main', [
m('h1', 'Mithril SPA'),
m(Counter),
m('hr'),
m(Counter),
m('hr'),
m(Counter)
])
}
}
const element = document.getElementById('app')
m.mount(element, Home)
3つのカウンターが表示されますが、それぞれ独自の状態(カウント)を持っていることが確認できます。
まとめ
Mirhtilの環境構築~基本動作の確認までを実施しました。
正直なところ、このような基本的な部分のみだと他フレームワークとの差が明確でないのも事実ですが、次回以降でMithrilの強み(シンプルさ)をより説明できたらと思っています。
ゆるく連載していきますので、気長にお待ち頂けると幸いです。
続き:コンポーネント編