Using Mix Templates with Phoenix S02E01

Show Notes

In this episode we are going to explore using the mix_templates utility created by Dave Thomas to make a template for Phoenix 1.3 that uses Webpack 2 instead of the default brunch. For a more in depth look at the tool itself I encourage you to watch Dave's screencast on just that.

The app is broken up into two separate utilities. The first mix_templates is responsible for processing and downloading templates from hex. mix_generator takes those templates and turns them into projects.

Lets install those both on our system.

$ mix archive.install hex mix_templates
$ mix archive.install hex mix_generator

Now that we have those installed lets generate a base phoenix project for our new template.

$ mix phx.new replace_me --no-brunch

I've prepared a webpack assets folder so I'll copy that over now.

$ cd replace_me
$ cp -r ../assets/ ./

Lets open up our editor and prepare the files to use as a template.

:args `find . -type f`
:argdo %s/ReplaceMe/<%= @project_name_camel_case %>/g | update
:argdo %s/replace_me/<%= @project_name %>/g | update

Since mix_templates also uses EEx to evaluate files if there is any embedded elixir that you don't want mix_templates to evaluate you'll need to change it from <%= fn(x) %> to <%%= fn(x) %> (notice the extra %). I'll go ahead and do that now for the layout/app.html.eex and page/index.html.eex.

To get auto reloading of our assets in the dev environment we'll have to update our watchers in config/dev.exs.

watchers: [npm: ["run", "dev",  
    cd: Path.expand("../assets", __DIR__)]]

Finally we'll want to make sure that our template generates a new secret for production each time it's ran. Lets update config/prod.secret.exs to make that happen.

<%= :crypto.strong_rand_bytes(64) |> Base.encode64 |> binary_part(0, 64) %>  

The project is in a pretty good place to be used as a template. We'll download the template for templates from hex. Then generate a new template using it.

$ cd ../
$ mix template.install hex gen_template_template
$ mix gen template why_not_webpack
$ cd why_not_webpack

We now have our template skeleton, lets copy over the phoenix template we created earlier and put it where it needs to go. We'll also need to rename the rename_me folder to make it dynamic.

$ cp -R ../replace_me/* template/\$PROJECT_NAME\$
$ mv template/\$PROJECT_NAME\$/lib/replace_me template/\$PROJECT_NAME\$/lib/\$PROJECT_NAME\$

Let's go ahead and give this template a try.

$ mix gen ./why_not_webpack phx_wp
** (UnicodeConversionError) invalid encoding starting at <<137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 216, 0, 0, 0, 99, 8, 6, 0, 0, 0, 161, 65, 119, 154, 0, 0, 0, 25, 116, 69, 88, 116, 83, 111, 102, 116, 119, 97, 114, 101, 0, ...>>

With the current version of mix_templates this should throw an error. The reason being is it's trying to use EEx to evaluated a png file. I'm working with Dave Thomas to get this fixed in a future version of mix_templates but for now we'll just delete the files from our template.

$ rm why_not_webpack/template/\$PROJECT_NAME\$/priv/static/images/phoenix.png
$ rm why_not_webpack/template/\$PROJECT_NAME\$/priv/static/favicon.ico
$ rm -rf phx_wp
$ mix gen ./why_not_webpack phx_wp

With that ran successfully we can now grab our dependencies, create our db and give this thing a try.

$ mix deps.get
$ mix deps.compile
$ cd assets/ && yarn install && cd ..
$ mix ecto.create

At this point we should have a working phoenix template. Lets fire up our phoenix server and take a look.

$ mix phx.server

As you can see webpack 2 is now handling our assets. Let's make sure our watcher is working by making a change to index.js.

alert("Hi from Webpack 2")  

There we go the change was detected and site auto reloaded for us, perfect! If you find yourself making the same changes over and over to the default phoenix stack, I highly suggest you create yourself a template and take advantage of Dave's mix_templates.

I'm here to help you out with your elixir journey so please reach out by email, twitter or on the elixir slack. Also if you'd like to suggest topics for future screencasts, or just wanna chat here's how to get ahold of me.

Email cory[at-sign]schmitty.me, twitter or cory on the elixir slack.