The purpose of this project is to demonstrate the process of adding Elm to a Phoenix web application, and then migrating from the Phoenix 1.2 layout to the new 1.3 layout. And most importantly, with elm-brunch correctly configured for the new layout.
- Install Elixir
- Install Hex:
mix local.hex
- Install Phoenix 1.2 generator:
mix archive.install https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez
- Install Node
Slightly unconventional database setup just because of my environment. In your case, just make sure you have PostgreSQL installed and running.
$ brew install postgresql
$ initdb -D postgres
$ pg_ctl -D postgres -l logfile start
$ psql postgres
postgres=# CREATE ROLE postgres LOGIN CREATEDB;
CREATE ROLE
postgres=# \q
If you are starting from scratch, you can follow these steps. If, on the other hand, you are cloning the repo in its current state and want to compile and test everything, skip to the bottom and follow those instructions.
$ mix phoenix.new elm_base
$ cd elm_base
$ mix deps.get
$ mix ecto.create
$ mix ecto.migrate
$ npm install
$ mix phoenix.server
Visit http://localhost:4000 to ensure the standard page is displayed.
There are blog posts and examples that cover basically this same recipe. I used slightly different paths here, since I feel that Elm is more akin to JavaScript than it is to Elixir, so I put the Elm code next to the other client-side assets. Also, I put the Elm code inside a src
directory, since that seems to be a reasonable convention.
$ mkdir -p web/static/elm/src
$ cd web/static/elm
$ elm-package install -y
Create web/static/elm/src/Main.elm
with a basic Html.text
"hello world" style message.
Edit source-directories
in elm-package.json
, changing .
to src
as mentioned above.
Install the elm-brunch plugin because it saves effort in the development cycle:
$ cd ../../..
$ npm i --save-dev elm-brunch
Add the following under plugins
in brunch-config.js
:
elmBrunch: {
elmFolder: "web/static/elm",
mainModules: ["src/Main.elm"],
outputFolder: "../vendor"
},
The outputFolder
setting, which is relative to the elmFolder
path, is vendor
for several reasons. First, it is automatically compiled and included before the app.js
code. Second, there is no need to require
or import
the Elm generated JavaScript in app.js
in order to use it. While it is possible to use the other approach, the first time brunch build
is run, it produces an error with regards to the import
of the JavaScript file that does not yet exist.
Replace the "marketing" div
in index.html.eex
with the following (partly just to eliminate some boilerplate, and also to keep the tests working with minimal changes):
<div id="elm-main"></div>
Add to, or replace entirely, the web/static/js/app.js
with the following:
const elmDiv = document.getElementById('elm-main');
if (elmDiv) {
Elm.Main.embed(elmDiv);
}
Run node node_modules/.bin/brunch build
to make sure everything builds.
Run mix phoenix.server
and make sure "Hello from Elm" appears on the web page.
Follow the steps as described in Chris McCord's migration guide, with some additional notes.
- Fixed a few additional paths in
brunch-config.js
, mostly aroundweb/static
. - Add
"elm"
to thepaths.watched
inbrunch-config.js
since theelm
directory is not in any of thewatched
folders after the layout change. - Go through the comments and make sure to apply any relevant errata.
If you have been following along from the very beginning...
$ rm -rf _build deps
$ mix deps.get
$ mix compile
$ mix test
$ cd assets
$ npm install
$ node node_modules/.bin/brunch build
$ cd ..
$ mix phx.server
If you are starting by cloning this repo in its current state...
$ mix deps.get
$ mix compile
$ mix ecto.create
$ mkdir -p priv/repo/migrations
$ mix ecto.migrate
$ mix test
$ cd assets
$ npm install
$ node node_modules/.bin/brunch build
$ cd ..
$ mix phx.server
Visit http://localhost:4000 to ensure you see the expected message from Elm. Bonus points if you check your browser's developer console for any errors.
When building for deployment, you will need to build two times, because of issue #35 in elm-brunch
.
$ cd assets
$ node node_modules/.bin/brunch build
$ node node_modules/.bin/brunch build