Help us understand the problem. What is going on with this article?

Railsで愉快な言語Elmを使う

More than 1 year has passed since last update.

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はまだ実験的サポートだということでしょうか。 

tonluqclml
エムスリーでソフトウェアエンジニアしています。仕事ではRubyもScalaもPythonもBashもなんでもやる雑食系。 Twitter:https://twitter.com/doloopwhile 昔の個人ブログ:http://doloopwhile.hatenablog.com/ 勤務先ブログ: https://www.m3tech.blog/
http://doloopwhile.hatenablog.com/
m3dev
インターネット、最新IT技術を活用し日本・世界の医療を改善することを目指します
https://m3.recruitment.jp/engineer/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away