Phoenix 1.5.x to 1.6 upgrade instructions
Update your deps
In mix.exs
, update your phoenix
, phoenix_html
, telemetry_metrics
, telemetry_poller
and phoenix_live_dashboard
deps, and add phoenix_live_view
:
def deps do
[
{:phoenix, "~> 1.6.0"},
...
{:phoenix_html, "~> 3.0"},
{:phoenix_live_view, "~> 0.16.4"},
{:phoenix_live_dashboard, "~> 0.5"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 0.5"},
...
]
end
Next, run mix deps.get
to grab your new deps.
Rename your .html.eex
and .html.leex
templates to .html.heex
(optional)
While leex templates have been deprecated, this step is optional. For the most part, existing templates should continue to work, but the HTML-aware HEEx engine will enforce valid markup and is more strict in the elixir expressions that appear within an open and closing tag. For example, the following code will raise:
<div id="<%= @id %>">
Instead of the standard <%= %>
EEx expressions, elixir expressions inside tags can only appear withing {}
, such as:
<div id={@id}>
<%= %>
expressions remain valid outside of HTML tags in the EEx engine.
To update your existing templates, rename all your .html.eex
and .html.leex
templats to .html.heex
and follow the parser errors to find any tags that require the new {}
attribute form.
Also be sure to review the HEEx documentation for more information on features.
Migrate to esbuild for js and css bundling (optional)
Phoenix's watchers
configuration is build-tool agnostic, so you may continue to enjoy your existing webpack configurations generated by phoenix 1.5 or earlier. If only have basic js and css needs and you would like to take advantage of our new esbuild
usage, for a dependency-free asset builder powered by a portably binary, follow these steps:
First delete your webpack config and related node files:
$ rm assets/webpack.config.js assets/package.json assets/package-lock.json assets/.babelrc
$ rm -rf assetes/node_modules
Next, add the esbuild
mix dep to your mix.exs
deps:
def deps do
[
...
{:esbuild, "~> 0.2", runtime: Mix.env() == :dev},
]
end
Next, configure esbuild in config/config.exs
:
# Configure esbuild (the version is required)
config :esbuild,
version: "0.12.18",
default: [
args: ~w(js/app.js --bundle --target=es2016 --outdir=../priv/static/assets),
cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
]
Next, replace the node watcher with esbuild in your endpoint watcher config in config/dev.exs
:
config :demo, DemoWeb.Endpoint,
...,
watchers: [
# Start the esbuild watcher by calling Esbuild.install_and_run(:default, args)
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]}
]
Next, add a new assets.deploy
mix alias in your mix.exs
for easy asset building:
defp aliases do
[
...,
"assets.deploy": ["esbuild default --minify", "phx.digest"]
]
end
Running $ mix assets.deploy
will download the esbuild binary on first run and then build your assets:
$ mix assets.deploy
21:40:37.588 [debug] Downloading esbuild from https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.12.18.tgz
../priv/static/assets/app.css 9.7kb
../priv/static/assets/app.js 1.3kb
⚡ Done in 12ms
Check your digested files at "priv/static"
Next, update your layouts, such as app.html.heex
or root.html.heex
to use the new assets
prefix instead of js/app.js
and css/app.css
:
<link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/app.css")}/>
<script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
Finally, update your Plug.Static
:only
options in your lib/app_web/endpoint.ex
to be aware of the new assets directory:
plug Plug.Static,
at: "/",
from: :my_app,
gzip: false,
only: ~w(assets fonts images favicon.ico robots.txt)
If you previously used the standalone
phx.gen.auth
and followed along with https://github.com/aaronrenner/phx_gen_auth_output to keep your code up-to-date, be sure to take note of this commit which occurred during the standalone->bundled transition.It may be why your test
test require_authenticated_user/2 stores the path to redirect to on GET
is failing.