Rails
Elm
Rails5

Railsで愉快な言語Elmを使う

Rails 5.1 でwebpackerが同梱されるようになりました。

この機会に新しいJSフレームワークに挑戦したいが、React・Vue・Angularのどれに挑戦するか迷っている、という人は多いでしょう。

しかーし!実はWebpackerには、もう一つのJSフレームワークがあるのです!


Elm って何だっけ?

詳しくは、公式ページ薄い本 などをご覧ください。

大雑把には、こんな特徴がある言語です。


  1. ElmはWEBページを、Haskellベースの言語で実装できる(ReactやVueのようなライブラリではない)

  2. Elmは予めブラウザが読める形式にコンパイルする(CoffeeScriptやTypeScriptのように)

  3. ElmはJavaScriptだけでなくHTMLやCSSも直接操作できる

  4. 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 にアクセスすると、面白みのないサンプル画面が表示できます。

image.png

ただし、右下に黒い操作履歴ウィジェットが表示されるのが、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アプリが動くようになりました!

image.png

また、右下の黒いウィジェットをクリックしてみましょう。

Elmは言語機能によって、状態をロジックと完全に分離しているので、アプリ側は何もしなくても 現在の内部状態を閲覧したりできます。

image.png


ハマりところ・残念だったところ

Elm は最新バージョンが v0.18 であり、まだ v1.0 が出ていません。そのため、言語仕様がしばしば変更されます。サンプルが動かない時は、elm-package.json のバージョンを調べてみてください。

また、webpacker では Native module (ElmのモジュールをJSで書ける機能)が、まだうまく動かないようなのが残念でした。


全体的な感想

ElmはFRPなど、先進的な機能が満載なので、大変勉強になるのですが、反面「実験的」「オモチャ」「実務では使えない」という印象が強いのが難点でした。

Railsアプリに埋め込めるということになれば、


  • インタラクティブ性が必要な部分はElmで書く

  • Elmで書きにくい部分はRailsに逃げる

と、使い分けられるようになったので、そろそろ実務で使い出してもいいんじゃないかな?と思いました。





  1. なぜか rails new --helpの説明文には--webpackelm を渡せるという説明がありません。Elmはまだ実験的サポートだということでしょうか。