Elixir 1.5 Umbrella App With Phoenix And Elm
It took me some time to figure out how this combination works. Finally, it is rather easy.
Starting from …
mix new myapp --umbrella
cd apps
mix phx.new myweb
… you should have a running Phoenix application now.
Add Elm
cd apps/myweb/lib/mywebweb/assets
npm install elm --save-dev
elm package install -y elm-lang/html
Add Your Elm App
mkdir assets/elm
mkdir assets/elm/src
touch assets/elm/src/Main.elm
Edit Main.elm
module Main exposing (..)
import Html exposing (h1, text, p, div)
import Html.Attributes exposing (style)
elmStyle =
style
[ ("backgroundColor", "darkred")
, ("height", "auto")
, ("width", "100%")
, ("color", "white")
, ("padding", "1em" )
]
main =
div [ elmStyle ]
[ h1 [] [ text "Hello, Elm!"]
, p [] [text "This is Elm in an elixir/phoenix umbrella app"]
]
Modify brunch-config.js
To
exports.config = {
files: {
javascripts: { joinTo: "js/app.js" },
stylesheets: { joinTo: "css/app.css" },
templates: { joinTo: "js/app.js" }
},
conventions: { assets: /^(static)/ },
paths: {
watched: ["static", "css", "js", "vendor", "elm"],
public: "../priv/static"
},
plugins: {
babel: { ignore: [/vendor/] },
elmBrunch: {
mainModules: ["elm/src/Main.elm" ],
makeParameters: ["--debug"],
outputFile: "elm.js",
outputFolder: "../assets/js"
}
},
modules: {
autoRequire: { "js/app.js": ["js/app"] }
},
npm: { enabled: true }
};
Add A “div” For The Elm Application
in any of your phoenix-template-files
<div id="elm-container"></div>
Add The Following Code To The End Of assets/app.js
// Elm
import Elm from "./elm";
const elmContainer = document.querySelector("#elm-container");
if (elmContainer) Elm.Main.embed(elmContainer);
Optional
If you’re using Git, you may add the following lines to your .gitignore file
apps/myweb/assets/js/elm.js
apps/myweb/assets/elm-stuff/
DONE
Your application should now show
wherever you put the div-tag mentioned above.
When you edit your Main.elm
application, brunch will compile all js-code and you should see your changes in the browser within the blink of an eye (no reload necessary).