Rails 5.1 でwebpackerが同梱されるようになりました。
この機会に新しいJSフレームワークに挑戦したいが、React・Vue・Angularのどれに挑戦するか迷っている、という人は多いでしょう。
しかーし!実はWebpackerには、もう一つのJSフレームワークがあるのです!
Elm って何だっけ?
大雑把には、こんな特徴がある言語です。
- ElmはWEBページを、Haskellベースの言語で実装できる(ReactやVueのようなライブラリではない)
- Elmは予めブラウザが読める形式にコンパイルする(CoffeeScriptやTypeScriptのように)
- ElmはJavaScriptだけでなくHTMLやCSSも直接操作できる
- Elmはモジュールなどの機能も含んでいる
ReactのJSXやES6が現実的にWEBを進歩させているのに対し、Elmは未来を行っていると言えるかもしれません。
Elm をインストールする
実はWebpackerがこっそりサポートしており特に難しいことはありません。ReactやVueと同じです。https://github.com/rails/webpacker#elm
アプリ作成時に --webpack=elm
をつけるだけです1
$ rails new myapp --webpack=elm
railsとwebpackのサーバーを起動します。
$ bin/rails server
$ bin/webpack-dev-server # 別コンソールなどで開く
ただし、初期状態ではWebpack側のJSをRails側が読み込んでいない(そもそもページが一つも無い)ので、適当なページを作り、Viewにjavascript_pack_tag
を仕込みます。
# app/views/examples/show.html.erb
<h1>Example</h1>
<%= javascript_pack_tag "hello_elm" %>
# config/routes.rb
Rails.application.routes.draw do
resource 'example', only: [:show]
end
# app/controllers/examples_controller.rb
class ExamplesController < ApplicationController
def show
end
end
http://localhost:3000/example にアクセスすると、面白みのないサンプル画面が表示できます。
ただし、右下に黒い操作履歴ウィジェットが表示されるのが、Elmの他と違うところです(後述)。
Elmの他のサンプルを使ってみる
Elm公式ページにある、多少複雑なSPAのサンプル動かしてみましょう。
Elmのソースは単にコピーするだけです。
$ git clone git@github.com:rtfeldman/elm-spa-example.git
$ cp -R elm-spa-example/src/* myapp/app/javascript/packs/
$ cp elm-spa-example/elm-package.json myapp/
elm-package.json のパスは、Webpackのものに書き換えます。
"source-directories": [
- "src"
+ "app/javascript/packs/"
],
また、elm-spa-exampleは外部のCSSも読み込んでいたので、application.html.erb
にCSSを追加します。
<!DOCTYPE html>
<html>
<head>
<title>Myapp</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<!-- Import Ionicon icons & Google Fonts our Bootstrap theme relies on -->
<link href="//code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Titillium+Web:700|Source+Serif+Pro:400,700|Merriweather+Sans:400,700|Source+Sans+Pro:400,300,600,700,300italic,400italic,600italic,700italic" rel="stylesheet" type="text/css">
<!-- Import the custom Bootstrap 4 theme from our hosted CDN -->
<link rel="stylesheet" href="//demo.productionready.io/main.css">
<style>/* Loading spinner courtesy of loader.io */
.sk-three-bounce { margin-right: 10px; } .sk-three-bounce .sk-child { width: 14px; height: 14px; background-color: #333; border-radius: 100%; display: inline-block; -webkit-animation: sk-three-bounce 1.4s ease-in-out 0s infinite both; animation: sk-three-bounce 1.4s ease-in-out 0s infinite both; } .sk-three-bounce .sk-bounce1 { -webkit-animation-delay: 0.28s; animation-delay: 0.28s; } .sk-three-bounce .sk-bounce2 { -webkit-animation-delay: 0.44s; animation-delay: 0.44s; } .sk-three-bounce .sk-bounce3 { -webkit-animation-delay: 0.6s; animation-delay: 0.6s; } @-webkit-keyframes sk-three-bounce { 0%, 80%, 100% { -webkit-transform: scale(0); transform: scale(0); } 40% { -webkit-transform: scale(1); transform: scale(1); } } @keyframes sk-three-bounce { 0%, 80%, 100% { -webkit-transform: scale(0); transform: scale(0); } 40% { -webkit-transform: scale(1); transform: scale(1); } }
</style>
</head>
<body>
<%= yield %>
</body>
</html>
ジャジャーン! Railsアプリの中で、Elmアプリが動くようになりました!
また、右下の黒いウィジェットをクリックしてみましょう。
Elmは言語機能によって、状態をロジックと完全に分離しているので、アプリ側は何もしなくても 現在の内部状態を閲覧したりできます。
ハマりところ・残念だったところ
Elm は最新バージョンが v0.18 であり、まだ v1.0 が出ていません。そのため、言語仕様がしばしば変更されます。サンプルが動かない時は、elm-package.json のバージョンを調べてみてください。
また、webpacker では Native module (ElmのモジュールをJSで書ける機能)が、まだうまく動かないようなのが残念でした。
全体的な感想
ElmはFRPなど、先進的な機能が満載なので、大変勉強になるのですが、反面「実験的」「オモチャ」「実務では使えない」という印象が強いのが難点でした。
Railsアプリに埋め込めるということになれば、
- インタラクティブ性が必要な部分はElmで書く
- Elmで書きにくい部分はRailsに逃げる
と、使い分けられるようになったので、そろそろ実務で使い出してもいいんじゃないかな?と思いました。
-
なぜか
rails new --help
の説明文には--webpack
にelm
を渡せるという説明がありません。Elmはまだ実験的サポートだということでしょうか。 ↩