Elm in Angular (CLI)

If you are into Elm but stuck in an existing application, the only real chance to move to Elm is by adding it gradually. Integrating Elm into any kind of web application is pretty easy. All you need to do is to compile your Elm to Javascript and load it.

elm-make src/elm/Main.elm --output=src/elm/main.js
const Elm = require('../elm/main');
Elm.Main.embed(document.getElementById('elm'));

So that part is dead-simple, but as web developers we are used to our CLIs, npm scripts, webpack, auto-reloading on changes and we really don’t want to give up on that.

Goal

We want to integrate Elm into our current development and build process without dropping any of our goodies. Edits made to any file (.elm | .js | .ts | .css | …) should lead to a reload with the changes.

I assume you already know angular, angular-cli and elm.

Angular CLI

Here is the full working github repo.

Create project

Run ng new ng-elm to create our example angular application.

ng create ng-elm

Eject from the CLI

In order for us to be able to modify the build process we need to have access to the webpack.config.js file. Since it is managed by the angular-cli we need to run ng eject which creates all the files for us.

ng eject

Create elm application

It’s time to create our example elm app we want to use in our angular app. We create a new file src/elm/Main.elm with the content of this example.

Import elm into angular-app

To import the Elm app lets first create the html where it should get loaded. In our app.component.html file we add the following lines anywhere.

<div>
<div id="elm">
</div>
</div>

Next we need to tell Elm to replace this div with the actual Elm application (app.component.ts).

ngAfterContentInit() {
const Elm = require('../elm/main');
Elm.Main.embed(document.getElementById('elm'));
}

Update webpack

For the last step we need to update the webpack.config.js file. For now it only builds and runs the angular app. First we install the necessary npm packages.

npm install --save-dev elm-hot-loader elm-webpack-loader

Next we add another entry in { module: { rules: [...] } }. This tells webpack to compile our Elm file.

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

And we need webpack to also check for .elm files. Update the extensions in { resolve: {...} } .

extensions: ['.ts', '.js', '.elm'],

Run it

npm run start

Now whenever you change an Elm file and save it, webpack will do its magic, compile the files and reload your browser. Just as we are used to. github repo