If you want a run-down of the 1.3 changes and the design decisions behidn those changes, check out the LonestarElixir Phoenix 1.3 keynote: https://www.youtube.com/watch?v=tMO28ar0lW8
To use the new phx.new project generator, you can install the archive with the following command:
$ mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez
Phoenix v1.3.0 is a backwards compatible release with v1.2.x. To upgrade your existing 1.2.x project, simply bump your phoenix dependency in mix.exs:
def deps do
[{:phoenix, "~> 1.3.0-rc"},
...]
endIf using the digest task (mix phoenix.digest), the location of the built manifest has changed from priv/static/manifest.json to priv/static/cache_manifest.json. Update your config/prod.exs endpoint config with the following changes:
-cache_static_manifest: "priv/static/manifest.json"
+cache_static_manifest: "priv/static/cache_manifest.json"Next, run mix deps.get and you're all set! Continue reading to jump on the latest project structure conventions (optional).
In mix.exs, update your elixirc_paths/1 clauses to remove "web":
- defp elixirc_paths(:test), do: ["lib", "web", "test/support"]
- defp elixirc_paths(_), do: ["lib", "web"]
+ defp elixirc_paths(:test), do: ["lib", "test/support"]
+ defp elixirc_paths(_), do: ["lib"]If you have a reloadable_paths configuration in your config/dev.exs, you may remove this value as all elixirc_paths are now reloaded in dev by default.
The root level web/ directory for new projects has been removed in favor of lib/my_app_web. Additionally, a Web namespace convention has been added to isolate the web interface from your elixir application.
Migrate your files to the new structure with the following steps:
$ cd my_app$ mv web/web.ex lib/my_app_web.ex$ mv web lib/my_app_web$ mv lib/my_app/endpoint.ex lib/my_app_web/- Update your view root path in
lib/my_app_web.exto point to the new template location, and add the:namespaceoption:
def view do
quote do
- use Phoenix.View, root: "web/templates"
+ use Phoenix.View, root: "lib/my_app_web/templates",
+ namespace: MyAppWeb
...- Add the namespace option to your
controllerdefinition inweb.ex:
def controller do
quote do
- use Phoenix.Controller
+ use Phoenix.Controller, namespace: MyAppWeb- Update your aliases in web.ex
controller,view, andchanneldefinitions to use the newWebnamespace:
def controller do
quote do
...
- import MyApp.Router.Helpers
+ import MyAppWeb.Router.Helpers
- import MyApp.Gettext
+ import MyAppWeb.Gettext
end
end
def view do
quote do
...
- import MyApp.Router.Helpers
+ import MyAppWeb.Router.Helpers
- import MyApp.ErrorHelpers
+ import MyAppWebErrorHelpers
- import MyApp.Gettext
+ import MyAppWeb.Gettext
end
end
def channel do
quote do
...
- import MyApp.Gettext
+ import MyAppWeb.Gettext
end
end- Rename all web related modules in
lib/my_app_web/(gettext.ex,controllers/*,views/*,channels/*,endpoint.ex,router.ex) to include aWebnamespace, for example:
MyApp.Endpoint=>MyAppWeb.EndpointMyApp.Router=>MyAppWeb.RouterMyApp.PageController=>MyAppWeb.PageControllerMyApp.PageView=>MyAppWeb.PageViewMyApp.UserSocket=>MyAppWeb.UserSocket- etc
- Update all alias in
lib/app_name_web/router.exto include newWebnamespace. Most likely you can accomplish this by addingWebto the second argument of your scope blocks, for example:
- defmodule MyApp.Router do
+ defmodule MyAppWeb.Router do
...
- scope "/", MyApp do
+ scope "/", MyAppWeb do
pipe_through :browser
resources "/users", UserController
...
end- Update
endpoint.exto use new web modules:
- defmodule MyApp.Endpoint do
+ defmodule MyAppWeb.Endpoint do
...
- socket "/socket", MyApp.UserSocket
+ socket "/socket", MyAppWeb.UserSocket
...
- plug MyApp.Router
+ plug MyAppWeb.Router- in
lib/my_app.ex, update your children to reference the new endpoint:
...
children = [
...
- supervisor(MyApp.Endpoint, []),
+ supervisor(MyAppWeb.Endpoint, []),
...
]
...- Update all endpoint aliases in config/*.exs (config.exs, prod.exs, prod.secret.exs dev.exs, test.exs, etc) aliases to use new
Webnamespace:
- config :my_app, MyApp.Endpoint,
+ config :my_app, MyAppWeb.Endpoint,
...
- render_errors: [view: MyApp.ErrorView, accepts: ~w(html json)],
+ render_errors: [view: MyAppWeb.ErrorView, accepts: ~w(html json)],
...- Update your live-reload patterns config in
config/dev.exs:
- config :my_app, MyApp.Endpoint,
+ config :my_app, MyAppWeb.Endpoint,
live_reload: [
patterns: [
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
~r{priv/gettext/.*(po)$},
- ~r{web/views/.*(ex)$},
- ~r{web/templates/.*(eex)$}
+ ~r{lib/my_app_web/views/.*(ex)$},
+ ~r{lib/my_app_web/templates/.*(eex)$}
]
]- Rename your
test/support/conn_case.exandtest/support/channel_case.exmodules to includeWebnamespace, and update@endpointand router aliases in each:
-defmodule MyApp.ConnCase do
+defmodule MyAppWeb.ConnCase do
using do
quote do
...
- import MyApp.Router.Helpers
+ import MyAppWeb.Router.Helpers
# The default endpoint for testing
- @endpoint MyApp.Endpoint
+ @endpoint MyAppWeb.Endpoint
end
end
...
-defmodule MyApp.ChannelCase do
+defmodule MyAppWeb.ChannelCase do
using do
quote do
...
- @endpoint MyApp.Endpoint
+ @endpoint MyAppWeb.Endpoint
end
end
...- Update all
test/*/**.exsreferences touse MyApp.ConnCaseoruse MyApp.ChannelCaseto use newMyAppWeb.ConnCaseandMyAppWeb.ChannelCasealiases.
New projects now include a root-level assets/ directory, which serves as a self-contained location for your asset builder's config, source files, and packages. This changer keeps things like node_modules, package.json, and brunch-config.js from leaking into the root of your elixir application. Update your app to the new structure by following these steps:
- move all
web/static/sources intoassets/, followed bypackage.json,node_modules, andbrunch-config.js
$ mv mv lib/my_app_web/static assets/
$ mv assets/assets assets/static
$ mv package.json assets/
$ mv brunch-config.js assets/
$ rm -rf node_modules- Update your
asset/package.jsonphoenixandphoenix_htmlpaths:
"dependencies": {
- "phoenix": "file:deps/phoenix",
+ "phoenix": "file:../deps/phoenix",
- "phoenix_html": "file:deps/phoenix_html"
+ "phoenix_html": "file:../deps/phoenix_html"
},- Update your
assets/brunch-config.jsto be aware of the new conventions:
conventions: {
- // This option sets where we should place non-css and non-js assets in.
- // By default, we set this to "/web/static/assets". Files in this directory
- // will be copied to `paths.public`, which is "priv/static" by default.
- assets: /^(web\/static\/assets)/
+ // This option sets where we should place non-css and non-js assets in.
+ // By default, we set this to "/assets/static". Files in this directory
+ // will be copied to `paths.public`, which is "priv/static" by default.
+ assets: /^(static)/
},
paths: {
// Dependencies and current project directories to watch
- watched: [
- "web/static",
- "test/static"
- ],
+ watched: ["static", "css", "js", "vendor"],
// Where to compile files to
- public: "priv/static"
+ public: "../priv/static"
},
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
- ignore: [/web\/static\/vendor/]
+ ignore: [/vendor/]
}
},
modules: {
autoRequire: {
- "js/app.js": ["web/static/js/app"]
+ "js/app.js": ["js/app"]
}
},- Update your
config/dev.exswatcher to run in the new assets directory:
config :my_app, MyAppWeb.Endpoint,
...
watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
- cd: Path.expand("../", __DIR__)]]
+ cd: Path.expand("../assets", __DIR__)]]
- Install the node deps:
$cd assets && npm install
Test it all with mix phx.server, and mix test and you should see:
$ mix phx.server
[info] Running MyAppWeb.Endpoint with Cowboy using http://0.0.0.0:4000
01 Mar 15:40:05 - info: compiled 6 files into 2 files, copied 3 in 976ms
Thanks @chenxsan