Using Rails 5.1 with Elm

Mitch

Warning - Old content ahead!

This page has been marked as a legacy post. This means it's quite old (from 2017) and probably out of date. Take it with a grain of salt!

Rails 5.1 comes with a lot changes for Javascript, making it easy to develop apps in Vue, React, and much more.

After a bit of playing around, here's how I've set up Elm with Webpack.

First make sure you have Rails 5.1 installed and Elm 0.18. This method will expect to use elm-make via webpack, so make sure it's available in your path. Webpacker also requires Node 6.4+, so make sure you have that installed, too.

Create a new rails app with --webpack

rails new app —webpack

Change in to the app directory and add the following Node packages with Yarn:

bin/yarn add elm elm-webpack-loader elm-hot-loader

Next we'll add the Foreman gem. This gem let's us use the webpack-dev-server alongside Rails.

# Gemfile
gem 'foreman'

Run bundle update afterwards to install the gem.

Create a Procfile in your project root for Foreman with the following 2 lines of code:

web: ./bin/rails server
webpack: ./bin/webpack-dev-server

Now we need to tell Webpack to look for .elm files. Go to config/webpack/paths.yml and add - .elm to the list (Note that order does matter, Putting .elm above .js will throw an error).

default: &default
  config: config/webpack
  entry: packs
  output: public
  manifest: manifest.json
  node_modules: node_modules
  source: app/javascript
  extensions:
    # ...
    - .coffee
    - .js
    - .elm

Go into the loaders directory and add elm.js with the following code:

//config/webpack/loaders/elm.js

module.exports = {
  test: /\.elm$/,
  exclude: [/elm-stuff/, /node_modules/],
  loader: 'elm-hot-loader!elm-webpack-loader?verbose=true&warn=true&debug=true'
}

Notice in line 6 that you can configure verbosity, warnings and debugging.

Finally, it's time to write some Elm! In your app/javascript/packs/ directory create Main.elm and add this basic Elm code.

module Main exposing (..)

import Html
import String


main : Html.Html msg
main =
    "Hello World"
        |> Html.text

In the adjacent application.js file (Still in the packs directory) import your Elm file and embed it in the div element of your choice.

var Elm = require('./Main');
Elm.Main.embed( document.getElementById( 'app' ) );

Go to your application layout (app/views/layouts/application.html.erb) and import the Javascript file with the Webpack helper just above your closing body tag and add the div element wherever you wish.

    <!-- ... -->
    <div id="app"></div>
    <%= javascript_pack_tag 'application' %>
  </body>

You'll need the elm-package.json to run the server, so go ahead and run elm-package install which will generate that for you.

All you need now is a view to display it in! If you haven't done this already, you can quickly create a route in config/routes.rb

get '/', to: 'application#index'

Then create view app/views/application/index.html.erb, if you put the div in the application layout, then you should now be able to see "Hello World" from Elm!

Spread the word

Share this article

Like this content?

Check out some of the apps that I've built!

Snipline

Command-line snippet manager for power users

View

Pinshard

Third party Pinboard.in app for iOS.

View

Rsyncinator

GUI for the rsync command

View

Comments