
Moon
Moonは軽量で高速なUIライブラリです。Mediumの「Introducing Moon」では開発された経緯と紹介、他のフレームワークとの比較がされています。
なぜMoonを採用するのか
公式資料ではMoonは軽量で高速なライブラリであると述べています。
- Preact - 3kb
- Moon - 7kb
- Mithril - 8kb
- Vue - 25.86kb
- React + React DOM - 43kb
- Angular - 111kb
パフォーマンスに関して、1秒間のレンダリング回数のベンチマークが取られています。Incremental-DOMとInfelnoも気になります。
- Moon - 102/min
- Mithril - 95/min
- Angular - 62/min
- Vue - 50/min
- React - 49/min
Moonはpolyfillを必要とせずにIE9+をサポートしています。AngularやVueのような最近のライブラリの殆どはBabelやTypeScriptを必要としIE9のサポートをやめています。
Vueのように、CDNが存在しそのままブラウザで動作させることができます。
UIの為にjQuery3のゴミを省いたスリムビルドでも67.3KBであることを考えると、7KBのMoonを採用する価値は十分にあります。
MoonはUIコンポーネントを可読性の高いコードで高速に構築することを重視しています、それはクライアントサイドルーティングの大規模なシングルページWebアプリケーションを構築するには、おそらく向いていません。
アプリケーション設計
VueとReactに関してはVuexやMobxのような他のライブラリがあるようにMoonにもMonxというライブラリがあります。
Monxは598 bytesのシンプルかつ軽量なデータフロー設計を助けるライブラリです。
コンポーネント間の状態の依存関係を取り出すことで、コンポーネントを綺麗にテストしやすいものにしてくれます。
初期のMobx-State-Treeから型定義を無くしたようなAPIで、読みやすいシンプルな文法で出来ています。
CLI
MoonにはCLIがあります。
今のところ、あまり多くの機能は無いみたいです。
$ npm install moon-cli -g$ moon init moon-example======= MOON =======[?] Author uufish[?] Description A Moon App[?] Moon Version 0.11.0✓ generating templatesuccess generated ‘moon-example’ ✨To Start, Run:cd moon-examplenpm installnpm run dev$ cd moon-example
必要なモジュールをインストールして起動します。

開発環境の生成が終わったらnpm-scriptのdevを実行します。
$ yarn$ yarn dev
開発環境が起動し、webサーバーが立ち上がります。
js/components/header.moonのtemplateを書き換えることでホットコードを体験することができます。かなり高速で反応します。
開発環境
Moonはfuse-boxやwebpackを必要としていません。buildというディレクトリが存在し、それをnodeで実行することでサーバーが起動します。
browserify-hmrやwatchifyといったモジュールが採用されています。コードも少なく読みやすいので、既存のプロジェクトにも簡単に導入することができます。
$ watchify -vd -e js/scripts.js -o dist/js/build.min.js -t moonify -p browserify-hmrMoonは.moonという拡張子のファイルをコンパイルします。テンプレートはVueにとても良く似ており、理解し易いです。
ただテンプレートの解析ができる環境を用意する必要があります。Atomではプラグインがあります。
コンポーネント
.moonでひとつのコンポーネントを設計できます。
<template>
<h1>{{content}}</h1>
</template>
<style scoped>
h1 {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
font-weight: 200;
font-size: 100px;
color: #414141;
}
</style>
<script>
exports = {
props: ["content"]
}
</script>ここで、contentはpropsであり、Html側から属性として渡すことができます。
<div id="app" m-mask>
<Header content="Moon"></Header>
</div>.moonのtemplateを見ればこれが、h1のchildrenであることがわかります。
このようにコンポーネントを使用したい場合は、コンポーネントを関数として実行します。
最後にMoon関数を実行することでレンダリングされます。
const Moon = require('moonjs')
const header = require('./components/header.moon')header(Moon)
new Moon({el: '#app'})
ライブラリ
UIライブラリを作りたいなら1つの.moonファイルを書くだけです。もし依存性注入のようなことがしたいのならmonxのstoreを書くのがいいかもしれません。
moon-barsというライブラリが参考になります。
また、設計に関してはサンプルがいくつかあります。みんなの愛するTodoMVCもちゃんとあります。
もし既存のサービスに、ポップアップやデイトピッカー、スナックバーのようなちょっとしたUIコンポーネントを実装したいなら、Moonを使用するといいかもしれません。

