darwin67
Detecting Mix.env in library
Hi folks,
What’s the current best practice when it comes to detecting env, something like Mix.env() within a library?
I’m currently building a library, and I’m trying to figure a good way for config to return different values based on environment it’s running on.
Based on library guidelines, config.exs is not recommended (and seems to be ignored when lib is used anyways), so I add a module like Library.Config. for returning config related values.
I tried something like this
defmodule Library.Config do
def url() do
if Mix.env() == :dev do
@dev_url
else
@event_url
end
end
end
which seem to work for local dev, but now I’m getting
Function Mix.env/0 does not exist.
from Dialyzer.
Would appreciate any recommendations or just pointing me to a direction.
Searching on this topic gets different results from the pass and seems like guidelines have been changing.
Also most questions seem to be more on usage within an application like Phoenix, and I don’t seem to be able to find much for library authors, so it’s not clear what’s the best way to proceed.
I’m fine with using something like Application.get_env, but unclear how the config values can be derived over to applications using the lib.
e.g.
# my lib config.exs
config :mylib, base_url: "https://someapp.com"
if Mix.env() == :dev do
config :mylib, base_url: "http://127.0.0.1:8288"
end
## application using mylib
iex -S mix> Application.get_env(:mylib, :base_url)
# => nil
Thanks
Marked As Solved
dimitarvp
As a corollary, you can use NimbleOptions to help you with having solid configuration values.
Also Liked
benwilson512
Libraries are always compiled with Mix.env == :prod, so I think toggling based on that isn’t going to work. Libraries should not change themselves implicitly, the user of the library should always pass in configuration. What changes are you trying to do?
trisolaran
If you need base_url to be set when you’re developing your library locally, then you already figured out how to do it:
# my lib config.exs
config :mylib, base_url: "https://someapp.com"
But if you need applications using the library to pass configuration to it, they will have to do so in their own config files. You should also consider whether it’s a good idea for your library to avoid using the application configuration altogether.
trisolaran
I wouldn’t do it for at least 2 reasons:
- libraries can also run outside of Mix, if your application is running in a release for example then Mix isn’t even available so the notion of an environment at runtime doesn’t even make sense
- environment names are completely defined by the application using your lib. Most people use standard names like
dev,test,prodetc. but they could use whatever. For all you know, they could usedevelopmentinstead ofdev
If your library needs to consume a configuration, then have your library’s user pass that in. Only that should matter, not the name of the environment
benwilson512
The convention in this case would be that your install instructions would tell users to do this in their runtime.exs
config :your_lib, endpoint: "127.0.0.1:8288"
if config_env() == :prod do
config :your_lib, endpoint: "[127.0.0.1:8288](https://inn.gs)"
end
Using the mix.env as a global variable to change logic in. your library both won’t work for the reasons I mentioned earlier, and is not a best practice.







