There are multiple ways to install Elixir dependencies. I wonder what happens in the following cases:
mix deps.get --only prod
What exactly dependencies are being fetched then?
defp deps do
[
{:credo, "~> 0.8", only: ~w(dev)a, runtime: false},
]
end
How only
option impact on a particular dependency?
def project do
[
# ...
deps: deps(Mix.env()),
]
end
What is the difference if we specify dependencies like that?
I'm confused a little bit when to use what regarding defining dependencies.
When you write this :
mix deps.get --only prod
It will fetch all dependencies for the prod environment, namely the dependencies where there is no only
option, and dependencies where the only
option is specified and containing :prod
(e.g {:some_dep, "~> 0.8", only: [:prod]}
)
When you write this :
defp deps do
[
{:some_dep, "~> 0.8"}
]
end
That tells mix to install some_dep
in any environment it is run into.
When you write this :
defp deps do
[
{:another_dep, "~> 0.8", only: [:dev]}
]
end
It tells mix to install another_dep
only when your environment is dev
(MIX_ENV=dev
).
If you are in any other environment (e.g. prod), mix deps.get
will simply ignore another_dep
and won't install it.
writing this :
def project do
[
# ...
deps: deps(Mix.env()),
]
end
will result in ** (CompileError) mix.exs:13: undefined function deps/1
because in your mix.exs
, only deps/0
is defined. Now you might tell me why not implement deps(:dev)
, deps(:prod)
and so on... Well, if you read what I explained before, you'll see that it is pointless, since the deps separation for each environment is already taken care of :)
I'm going to address these in reverse order.
using deps(Mix.env)
would force you to specify each of your dependencies multiple times if they are used across multiple environments. Something along the lines of
def deps(:dev) do
[
{:ecto, "~> 2.1"}
{:credo, "~> 0.8", runtime: false}
]
end
def deps(:test) do
[
{:ecto, "~> 2.1"}
]
end
I will admit that I do not even know if this would work, but this is adding too much code for something that is already handled for you if you just specify the :only
option.
Using :only
allows you to specify which environments a dependency should be used in. In your example, {:credo, "~> 0.8", only: [:dev], runtime: false}
you are telling mix that the credo package should only be used in the dev environment. If you do not include the :only
option, the package will be used in all environments.
$ mix deps.get --only prod
will only retrieve the packages relevant to the production environment. From the previous example, the credo package will not be retrieved because you told mix that credo should only be used in the dev environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With