Setting up a dev environment in Elm using Atom
It’s as easy as 1,2,… uhh.. 10 #
Our goal is to put together an Elm environment that includes custom HTML/SCSS and is suitable for a professional workflow for web applications.
The approach outlined here puts an emphasis on simplicity and minimal dependencies.
View the source code #
Features of this environment #
- Customise your index.html (for including css/js etc)
- Autocompile your Elm code on save (and view errors in IDE)
- Autocompile your scss
- Use elm-reactor as a local web server for development
Current limitations #
This approach does not yet support use of the elm debugger. If that is unsuitable for you then I encourage you to print this post out and throw it in the trash.
OK, Let’s do this thing. #
1. Install Atom IDE #
Get the Atom installer here. #
I chose Atom over Sublime Text (which is admittedly faster and more stable), Light Table, Microsoft VS Code because it currently has the best Elm language support and is easily extensible.
Maybe I’m backing the wrong horse here but so far Atom is working well for me.
2. Install these Atom packages: #
These can also be installed from within Atom via Settings > Install
3. Install Elm on your computer #
Get the Elm installer here. #
Easy.
4. Create your application directory structure and core files #
Type the following into your terminal (using Mac OSX - Windows is very similar. We’re just creating files and folders here)
mkdir MyApp
cd MyApp
mkdir src gen css
touch index.html src/Main.elm css/style.css save-commands.json
elm package install
elm package install evancz/elm-html
5. Configure save-commands to build your Elm files whenever you save them. #
The elm make
command is the officially supported build tool, so we can just automate that within our IDE instead of using a task runner like Grunt, Gulp, etc.
This part is a little tricky, as at the time of writing there are a couple bugs in this package that throw an error (details below). But it’s ok, we can get through this.
Open up the save-commands.json and enter the following in there.
save-commands.json #
{
"timeout": 5000,
"commands" : [
"src/**/*.elm : elm make src/Main.elm --output=gen/main.js"
]
}
Taking a look at that command in detail… the glob on the left of the colon tells save-commands when you want this command to run. Specifying src/**/*.elm
means that it will be run only when we save a file within the src
directory, or any of its subdirectories, as long as the file extension is .elm
The command itself is simply the manual elm make
command you would use if you weren’t using elm-reactor, targeting only src/Main.elm
and outputting it to gen/main.js
. The reason we don’t want target all .elm files in the src subdirectory to build is because elm-make is designed to find and compile the necessary dependencies based on the import
statements in your code.
Important note: you may get errors on save due to a couple bugs in save-commands. We’re gonna hack this ourselves today, but I expect these will be fixed in the future. Hopefully this will not be necessary in your case.
Commence the Hackery #
- In Atom, Go to Settings and click the Open Config Folder button
- Find save-commands code under packages > save-commands
- Line 107 replace
.find('.save-result')
with.getElementsByClassName('save-result')[0]
(as per this as-yet-unreleased PR) - Save and test
- If you get an error about
div.prop
not being a function, change Lines 114 and 124 fromdiv.scrollTop div.prop('.scrollHeight')
to justdiv.scrollTop
- Be a good citizen and submit a pull request for your well-considered, careful modifications
tl;dr this will compile the Main.elm file (and all imported elm modules) to main.js and it will compile whenever you save any .elm file within src, or any of it’s subdirectories.
6. Set up your styles #
This is going to look amazing.
style.scss #
body,
html {
font-family: "Comic Sans MS", cursive;
color: magenta;
}
When you save this file, sass-autocompile will produce a minified css file. Check out the docs to configure this as you like.
7. Set up Main.elm #
This will be your app’s entry point.
src/Main.elm #
module Main where
import Html exposing (text)
main =
text "wow"
When you save this file save-commands will run elm-make on it, compiling all your Elm code into into gen/main.js.
8. Set up your html #
index.html #
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My App</title>
<link rel="stylesheet" href="css/style.min.css">
</head>
<body>
<script src="gen/main.js"></script>
<script>
Elm.fullscreen(Elm.Main);
</script>
</body>
</html>
Your app structure should now look like this:
MyApp
├─ css
│ ├─ style.min.css
│ └─ style.scss
├─ elm-stuff
│ └─ ...
├─ gen
│ └─ main.js
├─ src
│ └─ Main.elm
├─ elm-package.json
├─ index.html
└─ save-commands.json
9. Start your local webserver #
Type this in the terminal from your app’s root directory.
elm reactor
10. Gaze upon the glory that is your new application #
Point your browser to localhost:8000/index.html
To verify that your Elm code is compiling on save, edit your Main.elm file and hit save.
src/Main.elm #
module Main where
import Html exposing (text)
main =
text "much wow...?"
Refresh your browser (auto-refresh/hot-swap would be nice here instead…) and you should see your changes.
Also notice that since save-commands outputs the results of elm-make in a Elm compiler in an Atom pane you won’t need to keep switching to your terminal or browser to see compiler errors!