by July 22, 2018
onAlthough the official Elm documentation does a great job at explaining how to build a new Elm appliation from the ground-up, it does miss out on the part on how you would integrate Elm into a proper project setup using Webpack for example.
In my early Elm days I searched through numerous example projects and popular Elm repositories on Github and picked up all the bits in small pieces. In this post I want to summarize the few steps on how to get started with an “Elm + Webpack” setup you can built upon.
At first we create a new Elm project using yarn
or npm
:
# create new project
$ yarn init
# install elm webpack integration
$ yarn add elm-webpack-loader file-loader
# install webpack development dependency
$ yarn add webpack webpack-cli webpack-dev-server -D
Now you can add some helper scripts into your newly created package.json
:
"scripts": {
"build": "webpack --mode production",
"dev": "webpack --mode development",
"client": "webpack-dev-server --port 3000 --mode development"
}
Next we are going to create a very basic webpack.config.js
that processes Elm files using the elm-webpack-loader
and the remaining files using a basic file-loader
:
var path = require('path');
module.exports = {
entry: {
app: [
'./src/index.js'
]
},
output: {
path: path.resolve(__dirname + '/dist'),
filename: '[name].js',
},
module: {
rules: [
{
test: /\.(css|scss)$/,
loader: 'file-loader?name=[name].[ext]',
},
{
test: /\.html$/,
exclude: /node_modules/,
loader: 'file-loader?name=[name].[ext]',
},
{
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 take a basic HTML index page stub, the Elm application will be injected into:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Elm + Webpack in 2 minutes</title>
</head>
<body>
<script src="app.js"></script>
</body>
</html>
The corresponding javascript entry point can start with something like the following:
'use strict';
require('./index.html');
var Elm = require('./Main.elm');
var app = Elm.Main.fullscreen();
/* in here you might register ports and such */
Now that we have a basic setup prepared we can write the first lines of Elm to start with:
module Main exposing ( main )
import Html exposing (..)
type Msg
= NoOp
type alias Model =
{ state : List String
}
initialModel : Model
initialModel = Model []
view : Model -> Html Msg
view model =
p [] [ text "hi, this was faster than 2 minutes right?!" ]
update : Msg -> Model -> Model
update msg model =
case msg of
NoOp -> model
main : Program Never Model Msg
main =
Html.beginnerProgram
{ model = initialModel
, view = view
, update = update
}
The lines above will look pretty familiar to everyone that has written or seen some Elm before - you can see the main components that drive basically every Elm application: a “model”, “view” and an “update” function.
That’s all we needed so far - let’s run it:
# build a production release
$ yarn build
# the resulting artifacts are placed into the 'dist' folder
$ firefox dist/index.html