ELM lang is a new language to write reliable web apps which will generate javascript with performance in focus and no runtime exceptions. To get started we need to go through the The Elm Architecture and understand the basic pattern of Model
, Update
and View
.
Once we were done we can start with playing with some snippets. In this post, we will cover
- How to setup ELM
- How to start playing with a Hello world example.
- How to bundle your app with webpack.
Installing ELM
If ELM is not installed in your system, the easiest way to install ELM is installing it from npm
.
npm install -g elm elm-live
elm will install elm-package
, elm-reactor
, elm-make
& elm-repl
and elm-live
is a flexible dev server with live reloading.
Setup ELM project
Since we have ELM installed in the system now, we can get started with installing the elm dependencies using elm package
in an empty directory.
elm package install
This will install elm-lang/core
, elm-lang/virtual-dom
& elm-lang/html
. Also this command will generate a elm-package.json
file.
A sample elm-package.json
will look like the one below.
// elm-package.json
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "5.1.1 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}
Now, let’s write a ELM program to show Hello World.
-- index.elm
import Html exposing (..)
import Html.Attributes exposing (..)
main = span [class "welcome"] [text "Hello World"]
Now, let’s run elm reactor
and open http://localhost:8000/
see its running in the browser.
We can run elm live
if we need the live reload for our development.
The hello world example have on View
part in the basic ELM pattern. Let’s look into another example
which has a Model
& Update
.
-- counter.elm
import Html exposing (..)
import Html.Events exposing (onClick)
type alias Model = Int
type Action = NoOp | Inc | Dec
update : Action -> Model -> ( Model, Cmd Action)
update action model =
case action of
NoOp -> (model, Cmd.none)
Inc -> (model + 1, Cmd.none)
Dec -> (model - 1, Cmd.none)
view : Model -> Html Action
view model =
div [] [
div [] [text "Counter"],
div [] [text ("From model :: " ++ (toString model))],
div [] [
button [onClick Dec] [text "-"],
span [] [text (toString model)],
button [onClick Inc] [text "+"]
]
]
init : ( Model, Cmd Action )
init =
(0, Cmd.none)
subscriptions : Model -> Sub Action
subscriptions model =
Sub.none
main =
Html.program {init = init, update = update, view = view, subscriptions = subscriptions}
Now we know how to run small ELM program, but when it comes to a real project we will be using bundling tools like
webpack
. Next, we will look into how we can bundle a ELM program with webpack. We will use the same counter program
to bundle and run with webpack.
Bundling with Webpack
We will start with setting up a index.html
& the entry point index.js
<!--index.html-->
<html>
<head>
<title>ELM Counter</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="elm-app"></div>
<script async src="app.js"></script>
</body>
</html>
The above snippet will assume that our webpack config will compile the ELM to app.js
.
Now the entry point index.js
need to take care of requiring counter.elm
and mounting the ELM app
in the div#elm-app
.
// index.js
'use strict';
var Elm = require('./counter.elm');
var mountNode = document.getElementById('elm-app');
// The third value on embed are the initial values for incomming ports into Elm
var app = Elm.Main.embed(mountNode);
Installing & configuring webpack
Let’s create a package.json
using npm init
command and then install the webpack and other dependencies.
npm install --save elm-webpack-loader webpack webpack-dev-server
Now let’s configure the webapack with elm-webpack-loader
.
// webpack.config.js
module.exports = {
entry: {
app: [
'./index.js'
]
},
output: {
filename: '[name].js',
},
module: {
loaders: [
{
test: /\.elm$/,
exclude: [/elm-stuff/, /node_modules/],
loader: 'elm-webpack-loader?verbose=true&warn=true',
},
],
noParse: /\.elm$/,
},
devServer: {
inline: true,
stats: { colors: true },
}
};
Now we are done with configuring webpack with elm loader, Let’s see this in action by executing the command
./node_modules/.bin/webpack-dev-server
and open the http://localhost:8081/
in the browser.