PJUllrich

PJUllrich

Author of Building Table Views with Phoenix LiveView

In my mix.exs I used to be able to call other Modules in order to fetch some configurations for my application-env configuration. Somehow this is not possible anymore since a few weeks (or the update to Elixir 1.11 maybe)

Here is an example of calling a module MyApp.Config.application_env() from inside my mix.exs file:

./mix.exs

defmodule MyApp.MixProject do
   use Mix.Project

     def project do
    [
      app: :my_app
      version: "0.2.0",
      elixir: "~> 1.5",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps(),
      test_paths: ["test", "lib"]
    ]
  end

  def application do
    [
      mod: {MyApp.Application, []},
      extra_applications: [:logger, :runtime_tools],
      env: MyApp.Config.application_env()
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  # deps and aliases ....

./lib/config.ex

defmodule MyApp.Config do
  def application_env do
    [my_config: "foo", another_config: "bar"]
  end
end

Since the update to Elixir 1.11 I cannot call this module anymore since the compiler complains like this:

** (UndefinedFunctionError) function MyApp.Config.application_env/0 is undefined (module MyApp.Config is not available)
    MyApp.Config.application_env()
    mix.exs:28: MyApp.MixProject.application/0
    (mix 1.11.0) lib/mix/tasks/compile.app.ex:382: Mix.Tasks.Compile.App.project_apps/1
    (mix 1.11.0) lib/mix/tasks/compile.all.ex:97: Mix.Tasks.Compile.All.load_apps/2
    (mix 1.11.0) lib/mix/tasks/compile.all.ex:24: Mix.Tasks.Compile.All.run/1
    (mix 1.11.0) lib/mix/task.ex:394: Mix.Task.run_task/3
    (mix 1.11.0) lib/mix/tasks/compile.ex:119: Mix.Tasks.Compile.run/1
    (mix 1.11.0) lib/mix/task.ex:394: Mix.Task.run_task/3

I tried require-ing and import-ing the MyApp.Config module, but nothing helped. The config.ex file is compiled and put into the _build/dev/ebin folder, but somehow it is not available during compile-time. I also tried to set it to an module attribute like this: @config MyApp.Config, but even this didn’t help.

I have the feeling that it is related to the latest Compilation time improvements in 1.11 which states:

This change allows us to mark import s and require s as “exports dependencies” instead of “compile time” dependencies

Does somebody know how to make my MyApp.Config module available at compile-time again?

Showing Posts 1 to 8

NobbZ

NobbZ

When mix.exs is evaluated your application is not available, as your application is built using the evaluation result of the mix.exs.

So by requiring your applications code within mix.exs you are creating a circular dependency that your application needs to be compiled in order to get compiled.

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

Hmm, that makes sense, but now I’m wondering why it worked before :thinking:

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

On another node: How can I then extract logic to set the application env option to another module/script/config file? I need to set default values for many application environment variables and don’t want to do this in every application which uses this library. So, I cannot use the config/... files since these are overwritten by the implementing applications, I believe. The advice in this thread was to use the application env option in mix.exs, which is why I use above setup. But I also don’t want to have 30 defp functions in my mix.exs and therefore extracting them to another module. Do you know a better/different way of setting a multitude of default values in a library maybe?

NobbZ

NobbZ

Try to refactor your library to not need to rely on those defaults…

If you insist on providing them, you could have a an extra file in the project root defining them and load it via Code.eval_file/2.

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

Thanks for the hint!

I used Code.compile_file/2 now in order to compile the MyApp.Config-module before setting the application env option like this:

def application do
  [{my_config, _binary}] = Code.compile_file("lib/config.ex")

  [
      mod: {MyApp.Application, []},
      extra_applications: [:logger, :httpoison, :runtime_tools, :cachex],
      env: my_config.application_env()
  ]
end
hauleth

hauleth

Out of interest - why? Why not other way around?

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

At work, we have ~5 Phoenix micro-services which all share some common libraries like a Neuron API-Client or a Cachex request handler. These libraries (Neuron, Cachex) need to be configured, both locally and on our servers, for the test, dev, and prod environments. We don’t want to copy&paste the same configuration to all our micro-services, which is why we bundled the libraries and their configuration in a library of our own. Since the config.exs of a library is ignored when the library is used in a project like one of our micro-services, we needed to put the shared configurations in the application env option of our own library. We have ~30 private functions which return a configuration for a “sub-library” so we didn’t want to put all these functions into our mix.exs, but in a separate Config-Module.

If you know a way to refactor this nicely, I would much appreciate to hear about it :slight_smile:

hauleth

hauleth

config.exs is ignored, but the :env in application is not. So if you have application that is using that, then you can configure it there. In general, it depends, as there is few possible solutions, depending on use case.

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews