I went from Phoenix
1.5 to 1.7 and I’m still facing an error when compiling the project.
elixir 1.17.3-otp-27
erlang 27.1
Here is the compilation error:
error: module Phoenix.Controller is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
2 │ use AppNameWeb, :html
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/controllers/error_html.ex:2: AppNameWeb.ErrorHTML (module)
error: module Gettext is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
21 │ use Gettext, backend: AppNameWeb.Gettext
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/components/core_components.ex:21: AppNameWeb.CoreComponents (module)
error: module Phoenix.Controller is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
2 │ use AppNameWeb, :controller
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/controllers/page_controller.ex:2: AppNameWeb.PageController (module)
error: module Phoenix.Controller is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
2 │ use AppNameWeb, :html
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/components/layouts.ex:2: AppNameWeb.Layouts (module)
== Compilation error in file lib/app_name_web/components/core_components.ex ==
** (CompileError) lib/app_name_web/components/core_components.ex: cannot compile module AppNameWeb.CoreComponents (errors have been logged)
(elixir 1.17.3) expanding macro: Kernel.use/2
lib/app_name_web/components/core_components.ex:21: AppNameWeb.CoreComponents (module)
It can also be:
error: module Phoenix.Component is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
17 │ use Phoenix.Component
│ ^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/components/core_components.ex:17: AppNameWeb.CoreComponents (module)
error: module Phoenix.Controller is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
2 │ use AppNameWeb, :controller
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/controllers/page_controller.ex:2: AppNameWeb.PageController (module)
error: module Phoenix.Component is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
2 │ use AppNameWeb, :html
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/components/layouts.ex:2: AppNameWeb.Layouts (module)
error: module Phoenix.Component is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
│
2 │ use AppNameWeb, :html
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
│
└─ lib/app_name_web/controllers/error_html.ex:2: AppNameWeb.ErrorHTML (module)
== Compilation error in file lib/app_name_web/components/core_components.ex ==
** (CompileError) lib/app_name_web/components/core_components.ex: cannot compile module AppNameWeb.CoreComponents (errors have been logged)
(elixir 1.17.3) expanding macro: Kernel.use/1
lib/app_name_web/components/core_components.ex:17: AppNameWeb.CoreComponents (module)
The mix.exs
before:
defmodule AppName.MixProject do
use Mix.Project
def project do
[
app: :app_name,
version: "0.1.5",
elixir: "~> 1.9",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
aliases: aliases(),
deps: deps(),
releases: [
app_name: [
include_executables_for: [:unix],
applications: [runtime_tools: :permanent]
]
]
]
end
# Configuration for the OTP application.
#
# Type `mix help compile.app` for more information.
def application do
[
mod: {AppName.Application, []},
extra_applications: [:logger, :runtime_tools, :google_maps, :edeliver]
]
end
# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# Specifies your project dependencies.
#
# Type `mix help deps` for examples and options.
defp deps do
[
{:ecto_sql, "~> 3.4"},
{:gettext, "~> 0.11"},
{:google_maps, "~> 0.11"},
{:distillery, "~> 2.1.1"},
{:edeliver, "~> 1.8.0"},
{:jason, "~> 1.0"},
{:phoenix, "~> 1.5.7"},
{:phoenix_ecto, "~> 4.1"},
{:phoenix_html, "~> 2.11"},
{:phoenix_live_dashboard, "~> 0.4"},
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:platformshconfig, "~> 0.1.0"},
{:plug_cowboy, "~> 2.0"},
{:telemetry_metrics, "~> 0.4"},
{:telemetry_poller, "~> 0.4"}
]
end
# Aliases are shortcuts or tasks specific to the current project.
# For example, to install project dependencies and perform other setup tasks, run:
#
# $ mix setup
#
# See the documentation for `Mix` for more info on aliases.
defp aliases do
[
setup: ["deps.get", "cmd npm install --prefix assets"]
]
end
end
The mix.exs
now:
defmodule AppName.MixProject do
use Mix.Project
def project do
[
app: :app_name,
version: "0.1.6",
elixir: "~> 1.9",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps(),
releases: [
app_name: [
include_executables_for: [:unix],
applications: [runtime_tools: :permanent]
]
]
]
end
# Configuration for the OTP application.
#
# Type `mix help compile.app` for more information.
def application do
[
applications: [
:edeliver
],
mod: {AppName.Application, []},
extra_applications: [:logger, :runtime_tools, :google_maps, :edeliver]
]
end
# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# Specifies your project dependencies.
#
# Type `mix help deps` for examples and options.
defp deps do
[
{:dart_sass, "~> 0.7", runtime: Mix.env() == :dev},
{:distillery, "~> 2.1"},
{:edeliver, ">= 1.9.2"},
{:esbuild, "~> 0.7", runtime: Mix.env() == :dev},
{:expo, "~> 0.5"},
{:gettext, "~> 0.25.0"},
{:google_maps, "~> 0.11"},
{:jason, "~> 1.0"},
{:phoenix, "~> 1.7"},
{:phoenix_html, "~> 3.0"},
{:phoenix_live_view, ">= 0.20.0"},
{:phoenix_live_dashboard, "~> 0.8.2"},
{:phoenix_live_reload, "~> 1.2"},
{:platformshconfig, "~> 0.1.0"},
{:plug_cowboy, "~> 2.5"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 0.5"}
]
end
# Aliases are shortcuts or tasks specific to the current project.
# For example, to install project dependencies and perform other setup tasks, run:
#
# $ mix setup
#
# See the documentation for `Mix` for more info on aliases.
defp aliases do
[
"assets.deploy": [
"sass default --no-source-map --style=compressed",
"esbuild default --minify",
"phx.digest"],
setup: ["deps.get"]
]
end
end
The file lib/app_name_web.ex
looks like that:
defmodule AppNameWeb do
@moduledoc """
The entrypoint for defining your web interface, such
as controllers, views, channels and so on.
This can be used in your application as:
use AppNameWeb, :controller
use AppNameWeb, :view
The definitions below will be executed for every view,
controller, etc, so keep them short and clean, focused
on imports, uses and aliases.
Do NOT define functions inside the quoted expressions
below. Instead, define any helper function in modules
and import those modules here.
"""
def static_paths do
~w(assets fonts images favicon.ico robots.txt)
end
def router do
quote do
use Phoenix.Router, helpers: false
import Plug.Conn
import Phoenix.Controller
import Phoenix.LiveView.Router
end
end
def controller do
quote do
use Phoenix.Controller,
formats: [:html, :json],
layouts: [html: AppNameWeb.Layouts]
import Plug.Conn
# import AppNameWeb.Gettext
use Gettext, backend: AppNameWeb.Gettext
unquote(verified_routes())
end
end
def html do
quote do
use Phoenix.Component
# Import convenience functions from controllers
import Phoenix.Controller,
only: [get_csrf_token: 0, view_module: 1, view_template: 1]
# Include general helpers for rendering HTML
unquote(html_helpers())
end
end
defp html_helpers do
quote do
# HTML escaping functionality
import Phoenix.HTML
# Core UI components and translation
import AppNameWeb.CoreComponents
# import AppNameWeb.Gettext
use Gettext, backend: AppNameWeb.Gettext
# Shortcut for generating JS commands
alias Phoenix.LiveView.JS
# Routes generation with the ~p sigil
unquote(verified_routes())
end
end
def verified_routes do
quote do
use Phoenix.VerifiedRoutes,
endpoint: AppNameWeb.Endpoint,
router: AppNameWeb.Router,
statics: AppNameWeb.static_paths()
end
end
@doc """
When used, dispatch to the appropriate controller/view/etc.
"""
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
end
Then, lib\app_name_web\components\core_components.ex
starts with:
defmodule AppNameWeb.CoreComponents do
@moduledoc """
Provides core UI components.
"""
use Phoenix.Component
alias Phoenix.LiveView.JS
# import AppNameWeb.Gettext
use Gettext, backend: AppNameWeb.Gettext
And finally, lib\app_name_web\gettext.ex
:
defmodule AppNameWeb.Gettext do
@moduledoc """
A module providing Internationalization with a gettext-based API.
"""
use Gettext.Backend, otp_app: :app_name
# use Gettext, otp_app: :app_name
end
I followed the tutorial here: Upgrading to Phoenix 1.7.
And (when I had a doubt) I checked on this project files:github.com/byronsalty/app_name.
It’s been few days now and I still struggle with this issue, I hope it’s a silly typo or something that can be fixed easily.
Thank you!