diff --git a/installer/lib/mix/tasks/phx.new.ex b/installer/lib/mix/tasks/phx.new.ex
index f4bdca798f..d88b912a8c 100644
--- a/installer/lib/mix/tasks/phx.new.ex
+++ b/installer/lib/mix/tasks/phx.new.ex
@@ -38,7 +38,7 @@ defmodule Mix.Tasks.Phx.New do
Please check the adapter docs for more information
and requirements. Defaults to "bandit".
- * `--no-assets` - equivalent to `--no-esbuild` and `--no-tailwind`
+ * `--no-assets` - equivalent to `--no-esbuild`, `--no-tailwind`, and disables Volt
* `--no-dashboard` - do not include Phoenix.LiveDashboard
@@ -63,6 +63,8 @@ defmodule Mix.Tasks.Phx.New do
are left-in as reference for the subsequent styling of your layout
and components
+ * `--volt` - use Volt instead of esbuild and tailwind for assets
+
* `--binary-id` - use `binary_id` as primary key type in Ecto schemas
* `--verbose` - use verbose output
@@ -158,6 +160,7 @@ defmodule Mix.Tasks.Phx.New do
assets: :boolean,
esbuild: :boolean,
tailwind: :boolean,
+ volt: :boolean,
ecto: :boolean,
app: :string,
module: :string,
@@ -266,6 +269,7 @@ defmodule Mix.Tasks.Phx.New do
defp validate_project(%Project{opts: opts} = project, path) do
check_app_name!(project.app, !!opts[:app])
+ check_volt_options!(opts)
check_directory_existence!(Map.fetch!(project, path))
check_module_name_validity!(project.root_mod)
check_module_name_availability!(project.root_mod)
@@ -297,17 +301,20 @@ defmodule Mix.Tasks.Phx.New do
if mix_step == [] do
builders = Keyword.fetch!(project.binding, :asset_builders)
+ installable_builders = Enum.reject(builders, &(&1 == :volt))
- if builders != [] do
+ if installable_builders != [] do
Mix.shell().info([:green, "* running ", :reset, "mix assets.setup"])
# First compile only builders so we can install in parallel
# TODO: Once we require Erlang/OTP 28, jason may no longer be required
- cmd(project, "mix deps.compile jason #{Enum.join(builders, " ")}", log: false)
+ cmd(project, "mix deps.compile jason #{Enum.join(installable_builders, " ")}",
+ log: false
+ )
end
tasks =
- Enum.map(builders, fn builder ->
+ Enum.map(installable_builders, fn builder ->
cmd = "mix do loadpaths --no-compile --no-listeners + #{builder}.install"
Task.async(fn -> cmd(project, cmd, log: false, cd: project.web_path) end)
end)
@@ -340,6 +347,13 @@ defmodule Mix.Tasks.Phx.New do
defp maybe_cd(path, func), do: path && File.cd!(path, func)
+ defp check_volt_options!(opts) do
+ if opts[:assets] != false && opts[:volt] &&
+ (opts[:esbuild] == false || opts[:tailwind] == false) do
+ Mix.raise("--volt cannot be combined with --no-esbuild or --no-tailwind")
+ end
+ end
+
defp install_mix(project, install?) do
if install? do
cmd(project, "mix deps.get")
diff --git a/installer/lib/phx_new/generator.ex b/installer/lib/phx_new/generator.ex
index 66bdd01fbd..f2b12f718d 100644
--- a/installer/lib/phx_new/generator.ex
+++ b/installer/lib/phx_new/generator.ex
@@ -244,8 +244,9 @@ defmodule Phx.New.Generator do
dashboard = Keyword.get(opts, :dashboard, true)
gettext = Keyword.get(opts, :gettext, true)
assets = Keyword.get(opts, :assets, true)
- esbuild = Keyword.get(opts, :esbuild, assets)
- tailwind = Keyword.get(opts, :tailwind, assets)
+ volt = assets and Keyword.get(opts, :volt, false)
+ esbuild = not volt and Keyword.get(opts, :esbuild, assets)
+ tailwind = not volt and Keyword.get(opts, :tailwind, assets)
mailer = Keyword.get(opts, :mailer, true)
dev = Keyword.get(opts, :dev, false)
from_elixir_install = Keyword.get(opts, :from_elixir_install, false)
@@ -282,6 +283,26 @@ defmodule Phx.New.Generator do
:error -> adapter_config
end
+ asset_builders =
+ if volt,
+ do: [:volt],
+ else: Enum.filter([tailwind && :tailwind, esbuild && :esbuild], & &1)
+
+ {assets_setup, assets_build, assets_deploy} =
+ if volt do
+ volt_profile = if project.in_umbrella?, do: " #{project.web_app}", else: ""
+
+ {[],
+ ["compile", "volt.build#{volt_profile} --tailwind"],
+ ["volt.build#{volt_profile} --tailwind", "phx.digest"]}
+ else
+ {
+ Enum.map(asset_builders, &"#{&1}.install --if-missing"),
+ ["compile" | Enum.map(asset_builders, &"#{&1} #{project.web_app}")],
+ Enum.map(asset_builders, &"#{&1} #{project.web_app} --minify") ++ ["phx.digest"]
+ }
+ end
+
binding = [
app_name: project.app,
app_module: inspect(project.app_mod),
@@ -301,9 +322,13 @@ defmodule Phx.New.Generator do
signing_salt: random_string(8),
lv_signing_salt: random_string(8),
in_umbrella: project.in_umbrella?,
- asset_builders: Enum.filter([tailwind && :tailwind, esbuild && :esbuild], & &1),
- javascript: esbuild,
- css: tailwind,
+ asset_builders: asset_builders,
+ assets_setup: assets_setup,
+ assets_build: assets_build,
+ assets_deploy: assets_deploy,
+ javascript: volt or esbuild,
+ css: volt or tailwind,
+ volt: volt,
mailer: mailer,
ecto: ecto,
html: html,
diff --git a/installer/lib/phx_new/interactive.ex b/installer/lib/phx_new/interactive.ex
index 0df7c46f8d..6048bd94b1 100644
--- a/installer/lib/phx_new/interactive.ex
+++ b/installer/lib/phx_new/interactive.ex
@@ -15,6 +15,12 @@ defmodule Phx.New.Interactive do
{"api", "API-only"}
]
+ @asset_options [
+ {"esbuild", "Esbuild + Tailwind"},
+ {"volt", "Volt"},
+ {"none", "None"}
+ ]
+
def run do
catch_abort(fn ->
info([:green, "\nInitialize your Phoenix project (press Ctrl+C to abort)\n", :reset])
@@ -29,7 +35,7 @@ defmodule Phx.New.Interactive do
yes?("Use binary_id as primary key type?", false)
end
- %{html: html, live: live, assets: assets} = prompt_web()
+ %{html: html, live: live, assets: assets, volt: volt} = prompt_web()
dashboard = yes?("Include LiveDashboard (monitoring)?")
mailer = yes?("Include Swoosh (mailer)?")
gettext = yes?("Include Gettext (i18n)?")
@@ -43,7 +49,8 @@ defmodule Phx.New.Interactive do
dashboard: dashboard,
mailer: mailer,
gettext: gettext,
- assets: assets
+ assets: assets,
+ volt: volt
]
|> maybe_put_database(database)
@@ -78,13 +85,19 @@ defmodule Phx.New.Interactive do
defp prompt_web do
case prompt_choice("Web interface?", @web_options, "live") do
- "api" -> %{html: false, live: false, assets: false}
- "html" -> %{html: true, live: false, assets: prompt_assets?()}
- "live" -> %{html: true, live: true, assets: prompt_assets?()}
+ "api" -> %{html: false, live: false, assets: false, volt: false}
+ "html" -> Map.merge(%{html: true, live: false}, prompt_assets())
+ "live" -> Map.merge(%{html: true, live: true}, prompt_assets())
end
end
- defp prompt_assets?, do: yes?("Include Esbuild + Tailwind?")
+ defp prompt_assets do
+ case prompt_choice("Assets?", @asset_options, "esbuild") do
+ "esbuild" -> %{assets: true, volt: false}
+ "volt" -> %{assets: true, volt: true}
+ "none" -> %{assets: false, volt: false}
+ end
+ end
defp prompt_choice(question, choices, default) do
info("\n#{question}\n")
@@ -146,12 +159,14 @@ defmodule Phx.New.Interactive do
end
defp web_summary(opts) do
- case {opts[:html], opts[:live], opts[:assets]} do
- {true, true, true} -> "LiveView"
- {true, true, false} -> "LiveView (no Esbuild, no Tailwind)"
- {true, false, true} -> "HTML"
- {true, false, false} -> "HTML (no Esbuild, no Tailwind)"
- {false, _, _} -> "API-only"
+ case {opts[:html], opts[:live], opts[:assets], opts[:volt]} do
+ {true, true, true, true} -> "LiveView (Volt)"
+ {true, true, true, _} -> "LiveView"
+ {true, true, false, _} -> "LiveView (no Esbuild, no Tailwind)"
+ {true, false, true, true} -> "HTML (Volt)"
+ {true, false, true, _} -> "HTML"
+ {true, false, false, _} -> "HTML (no Esbuild, no Tailwind)"
+ {false, _, _, _} -> "API-only"
end
end
@@ -166,7 +181,8 @@ defmodule Phx.New.Interactive do
{!opts[:dashboard], "--no-dashboard"},
{!opts[:mailer], "--no-mailer"},
{!opts[:gettext], "--no-gettext"},
- {!opts[:assets], "--no-assets"}
+ {!opts[:assets], "--no-assets"},
+ {opts[:volt], "--volt"}
],
condition,
do: flag
diff --git a/installer/templates/phx_assets/app.js.eex b/installer/templates/phx_assets/app.js.eex
index f22e06639f..ffe0bfa4cd 100644
--- a/installer/templates/phx_assets/app.js.eex
+++ b/installer/templates/phx_assets/app.js.eex
@@ -14,7 +14,7 @@
//
// import "some-package"
//
-// If you have dependencies that try to import CSS, esbuild will generate a separate `app.css` file.
+// If you have dependencies that try to import CSS, <%= if @volt, do: "Volt", else: "esbuild" %> will generate a separate `app.css` file.
// To load it, simply add a second `` to your `root.html.heex` file.
<%= if @html do %>
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
@@ -52,7 +52,7 @@ import "phoenix_html"
// 1. stream server logs to the browser console
// 2. click on elements to jump to their definitions in your code editor
//
-<%= @live_comment %>if (process.env.NODE_ENV === "development") {
+<%= @live_comment %>if (<%= if @volt, do: "import.meta.env.DEV", else: "process.env.NODE_ENV === \"development\"" %>) {
<%= @live_comment %> window.addEventListener("phx:live_reload:attached", ({detail: reloader}) => {
<%= @live_comment %> // Enable server log streaming to client.
<%= @live_comment %> // Disable with reloader.disableServerLogs()
diff --git a/installer/templates/phx_assets/tsconfig.json.eex b/installer/templates/phx_assets/tsconfig.json.eex
index a9401b623c..870c7a5d1c 100644
--- a/installer/templates/phx_assets/tsconfig.json.eex
+++ b/installer/templates/phx_assets/tsconfig.json.eex
@@ -1,8 +1,8 @@
// This file is needed on most editors to enable the intelligent autocompletion
// of LiveView's JavaScript API methods. You can safely delete it if you don't need it.
//
-// Note: This file assumes a basic esbuild setup without node_modules.
-// We include a generic paths alias to deps to mimic how esbuild resolves
+// Note: This file assumes a basic <%= if @volt, do: "Volt", else: "esbuild" %> setup without node_modules.
+// We include a generic paths alias to deps to mimic how <%= if @volt, do: "Volt", else: "esbuild" %> resolves
// the Phoenix and LiveView JavaScript assets.
// If you have a package.json in your project, you should remove the
// paths configuration and instead add the phoenix dependencies to the
diff --git a/installer/templates/phx_single/config/config.exs.eex b/installer/templates/phx_single/config/config.exs.eex
index 11496cdbc4..db862d56d7 100644
--- a/installer/templates/phx_single/config/config.exs.eex
+++ b/installer/templates/phx_single/config/config.exs.eex
@@ -31,7 +31,23 @@ config :<%= @app_name %>, <%= @endpoint_module %>,
#
# For production it's recommended to configure a different adapter
# at the `config/runtime.exs`.
-config :<%= @app_name %>, <%= @app_module %>.Mailer, adapter: Swoosh.Adapters.Local<% end %><%= if @javascript do %>
+config :<%= @app_name %>, <%= @app_module %>.Mailer, adapter: Swoosh.Adapters.Local<% end %><%= if @volt do %>
+
+# Configure Volt
+config :volt,
+ entry: "assets/js/app.js",
+ outdir: "priv/static/assets",
+ target: :es2022,
+ hash: false,
+ sourcemap: :hidden,
+ resolve_dirs: [Path.expand("../deps", __DIR__), Mix.Project.build_path()],
+ tailwind: [
+ css: "assets/css/app.css",
+ sources: [
+ %{base: "lib/", pattern: "**/*.{ex,heex,eex}"},
+ %{base: "assets/", pattern: "**/*.{js,ts,jsx,tsx}"}
+ ]
+ ]<% else %><%= if @javascript do %>
# Configure esbuild (the version is required)
config :esbuild,
@@ -52,7 +68,7 @@ config :tailwind,
--output=priv/static/assets/css/app.css
),
cd: Path.expand("..<%= if @in_umbrella, do: "/apps/#{@app_name}" %>", __DIR__),
- ]<% end %>
+ ]<% end %><% end %>
# Configure Elixir's Logger
config :logger, :default_formatter,
diff --git a/installer/templates/phx_single/config/dev.exs.eex b/installer/templates/phx_single/config/dev.exs.eex
index 165a158c7d..bfd245aae7 100644
--- a/installer/templates/phx_single/config/dev.exs.eex
+++ b/installer/templates/phx_single/config/dev.exs.eex
@@ -18,10 +18,16 @@ config :<%= @app_name %>, <%= @endpoint_module %>,<%= if @inside_docker_env? do
code_reloader: true,
debug_errors: true,
secret_key_base: "<%= @secret_key_base_dev %>",
- watchers: <%= if @javascript or @css do %>[<%= if @javascript do %>
+ watchers: <%= if @volt do %>[
+ volt: {Mix.Tasks.Volt.Dev, :run, [~w(--tailwind)]}
+ ]<% else %><%= if @javascript or @css do %>[<%= if @javascript do %>
esbuild: {Esbuild, :install_and_run, [:<%= @app_name %>, ~w(--sourcemap=inline --watch)]}<%= if @css, do: "," %><% end %><%= if @css do %>
tailwind: {Tailwind, :install_and_run, [:<%= @app_name %>, ~w(--watch)]}<% end %>
- ]<% else %>[]<% end %>
+ ]<% else %>[]<% end %><% end %><%= if @volt do %>
+
+config :volt, :server,
+ prefix: "/assets",
+ watch_dirs: ["lib/"]<% end %>
# ## SSL Support
#
diff --git a/installer/templates/phx_single/formatter.exs.eex b/installer/templates/phx_single/formatter.exs.eex
index 71188d1921..c334a0f38d 100644
--- a/installer/templates/phx_single/formatter.exs.eex
+++ b/installer/templates/phx_single/formatter.exs.eex
@@ -1,6 +1,6 @@
[
import_deps: [<%= if @ecto do %>:ecto, :ecto_sql, <% end %>:phoenix],<%= if @ecto do %>
- subdirectories: ["priv/*/migrations"],<% end %><%= if @html do %>
- plugins: [Phoenix.LiveView.HTMLFormatter],<% end %>
- inputs: [<%= if @html do %>"*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}"<% else %>"*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"<% end %><%= if @ecto do %>, "priv/*/seeds.exs"<% end %>]
+ subdirectories: ["priv/*/migrations"],<% end %><%= if @html or @volt do %>
+ plugins: [<%= Enum.join(Enum.filter([@html && "Phoenix.LiveView.HTMLFormatter", @volt && "Volt.Formatter"], & &1), ", ") %>],<% end %>
+ inputs: [<%= if @html do %>"*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}"<% else %>"*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"<% end %><%= if @ecto do %>, "priv/*/seeds.exs"<% end %><%= if @volt do %>, "assets/**/*.{js,ts,jsx,tsx}"<% end %>]
]
diff --git a/installer/templates/phx_single/mix.exs.eex b/installer/templates/phx_single/mix.exs.eex
index abbaa1b405..0ab4284999 100644
--- a/installer/templates/phx_single/mix.exs.eex
+++ b/installer/templates/phx_single/mix.exs.eex
@@ -52,9 +52,10 @@ defmodule <%= @app_module %>.MixProject do
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_view, "~> 1.1.0"},
{:lazy_html, ">= 0.1.0", only: :test},<% end %><%= if @dashboard do %>
- {:phoenix_live_dashboard, "~> 0.8.3"},<% end %><%= if @javascript do %>
+ {:phoenix_live_dashboard, "~> 0.8.3"},<% end %><%= if @volt do %>
+ {:volt, "~> 0.11.0"},<% else %><%= if @javascript do %>
{:esbuild, "~> 0.10", runtime: Mix.env() == :dev},<% end %><%= if @css do %>
- {:tailwind, "~> 0.3", runtime: Mix.env() == :dev},
+ {:tailwind, "~> 0.3", runtime: Mix.env() == :dev},<% end %><% end %><%= if @css do %>
{:heroicons,
github: "tailwindlabs/heroicons",
tag: "v2.2.0",
@@ -85,11 +86,9 @@ defmodule <%= @app_module %>.MixProject do
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"]<% end %><%= if @asset_builders != [] do %>,
- "assets.setup": <%= inspect Enum.map(@asset_builders, &"#{&1}.install --if-missing") %>,
- "assets.build": <%= inspect ["compile" | Enum.map(@asset_builders, &"#{&1} #{@app_name}")] %>,
- "assets.deploy": [
-<%= Enum.map(@asset_builders, &" \"#{&1} #{@app_name} --minify\",\n") ++ [" \"phx.digest\""] %>
- ]<% end %>,
+ "assets.setup": <%= inspect @assets_setup %>,
+ "assets.build": <%= inspect @assets_build %>,
+ "assets.deploy": <%= inspect @assets_deploy %><% end %>,
precommit: ["compile --warnings-as-errors", "deps.unlock --unused", "format", "test"]
]
end
diff --git a/installer/templates/phx_umbrella/apps/app_name_web/config/config.exs.eex b/installer/templates/phx_umbrella/apps/app_name_web/config/config.exs.eex
index dc0792d165..db99a98883 100644
--- a/installer/templates/phx_umbrella/apps/app_name_web/config/config.exs.eex
+++ b/installer/templates/phx_umbrella/apps/app_name_web/config/config.exs.eex
@@ -15,7 +15,23 @@ config :<%= @web_app_name %>, <%= @endpoint_module %>,
layout: false
],
pubsub_server: <%= @app_module %>.PubSub,
- live_view: [signing_salt: "<%= @lv_signing_salt %>"]<%= if @javascript do %>
+ live_view: [signing_salt: "<%= @lv_signing_salt %>"]<%= if @volt do %>
+
+# Configure Volt
+config :volt, :<%= @web_app_name %>,
+ entry: "assets/js/app.js",
+ outdir: "priv/static/assets",
+ target: :es2022,
+ hash: false,
+ sourcemap: :hidden,
+ resolve_dirs: [Path.expand("../deps", __DIR__), Mix.Project.build_path()],
+ tailwind: [
+ css: "assets/css/app.css",
+ sources: [
+ %{base: "lib/", pattern: "**/*.{ex,heex,eex}"},
+ %{base: "assets/", pattern: "**/*.{js,ts,jsx,tsx}"}
+ ]
+ ]<% else %><%= if @javascript do %>
# Configure esbuild (the version is required)
config :esbuild,
@@ -36,4 +52,4 @@ config :tailwind,
--output=priv/static/assets/css/app.css
),
cd: Path.expand("../apps/<%= @web_app_name %>", __DIR__)
- ]<% end %>
+ ]<% end %><% end %>
diff --git a/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs.eex b/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs.eex
index 8c01968cde..7cc421876f 100644
--- a/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs.eex
+++ b/installer/templates/phx_umbrella/apps/app_name_web/config/dev.exs.eex
@@ -18,10 +18,12 @@ config :<%= @web_app_name %>, <%= @endpoint_module %>,<%= if @inside_docker_env?
code_reloader: true,
debug_errors: true,
secret_key_base: "<%= @secret_key_base_dev %>",
- watchers: <%= if @javascript or @css do %>[<%= if @javascript do %>
+ watchers: <%= if @volt do %>[
+ volt: {Mix.Tasks.Volt.Dev, :run, [~w(<%= @web_app_name %> --tailwind)]}
+ ]<% else %><%= if @javascript or @css do %>[<%= if @javascript do %>
esbuild: {Esbuild, :install_and_run, [:<%= @web_app_name %>, ~w(--sourcemap=inline --watch)]}<%= if @css, do: "," %><% end %><%= if @css do %>
tailwind: {Tailwind, :install_and_run, [:<%= @web_app_name %>, ~w(--watch)]}<% end %>
- ]<% else %>[]<% end %>
+ ]<% else %>[]<% end %><% end %>
# ## SSL Support
#
diff --git a/installer/templates/phx_umbrella/apps/app_name_web/formatter.exs.eex b/installer/templates/phx_umbrella/apps/app_name_web/formatter.exs.eex
index 4ea75e02d1..083a2692a2 100644
--- a/installer/templates/phx_umbrella/apps/app_name_web/formatter.exs.eex
+++ b/installer/templates/phx_umbrella/apps/app_name_web/formatter.exs.eex
@@ -1,5 +1,5 @@
[
- import_deps: [:phoenix],<%= if @html do %>
- plugins: [Phoenix.LiveView.HTMLFormatter],<% end %>
- inputs: [<%= if @html do %>"*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}"<% else %>"*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"<% end %>]
+ import_deps: [:phoenix],<%= if @html or @volt do %>
+ plugins: [<%= Enum.join(Enum.filter([@html && "Phoenix.LiveView.HTMLFormatter", @volt && "Volt.Formatter"], & &1), ", ") %>],<% end %>
+ inputs: [<%= if @html do %>"*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}"<% else %>"*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"<% end %><%= if @volt do %>, "assets/**/*.{js,ts,jsx,tsx}"<% end %>]
]
diff --git a/installer/templates/phx_umbrella/apps/app_name_web/mix.exs.eex b/installer/templates/phx_umbrella/apps/app_name_web/mix.exs.eex
index 842b551ce3..9ff0279e2b 100644
--- a/installer/templates/phx_umbrella/apps/app_name_web/mix.exs.eex
+++ b/installer/templates/phx_umbrella/apps/app_name_web/mix.exs.eex
@@ -44,9 +44,10 @@ defmodule <%= @web_namespace %>.MixProject do
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_live_view, "~> 1.1.0"},
{:lazy_html, ">= 0.1.0", only: :test},<% end %><%= if @dashboard do %>
- {:phoenix_live_dashboard, "~> 0.8.3"},<% end %><%= if @javascript do %>
+ {:phoenix_live_dashboard, "~> 0.8.3"},<% end %><%= if @volt do %>
+ {:volt, "~> 0.11.0"},<% else %><%= if @javascript do %>
{:esbuild, "~> 0.10", runtime: Mix.env() == :dev},<% end %><%= if @css do %>
- {:tailwind, "~> 0.3", runtime: Mix.env() == :dev},
+ {:tailwind, "~> 0.3", runtime: Mix.env() == :dev},<% end %><% end %><%= if @css do %>
{:heroicons,
github: "tailwindlabs/heroicons",
tag: "v2.2.0",
@@ -70,11 +71,9 @@ defmodule <%= @web_namespace %>.MixProject do
[
setup: ["deps.get"<%= if @asset_builders != [] do %>, "assets.setup", "assets.build"<% end %>]<%= if @ecto do %>,
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"]<% end %><%= if @asset_builders != [] do %>,
- "assets.setup": <%= inspect Enum.map(@asset_builders, &"#{&1}.install --if-missing") %>,
- "assets.build": <%= inspect ["compile" | Enum.map(@asset_builders, &"#{&1} #{@web_app_name}")] %>,
- "assets.deploy": [
-<%= Enum.map(@asset_builders, &" \"#{&1} #{@web_app_name} --minify\",\n") ++ [" \"phx.digest\""] %>
- ]<% end %>
+ "assets.setup": <%= inspect @assets_setup %>,
+ "assets.build": <%= inspect @assets_build %>,
+ "assets.deploy": <%= inspect @assets_deploy %><% end %>
]
end
end
diff --git a/installer/templates/phx_web/components/layouts/root.html.heex.eex b/installer/templates/phx_web/components/layouts/root.html.heex.eex
index e2ac3f4587..a077ff1c79 100644
--- a/installer/templates/phx_web/components/layouts/root.html.heex.eex
+++ b/installer/templates/phx_web/components/layouts/root.html.heex.eex
@@ -6,9 +6,11 @@
<.live_title default="<%= @app_module %>" suffix=" ยท Phoenix Framework" phx-no-format>{assigns[:page_title]}
<%= if not @css do %>
- <% end %>
+ <% end %><%= if @volt do %>
+ <% else %>
<%= if @css do %>
+ <% end %><%= if @css do %>