I’m struggling with optional: true
dependencies in one of my projects. This project will wrap an API (complete code here), and users will be able to provide their own functions/modules to handle the HTTP interaction and response body decoding if they wish. However, default implementations of these will ship with the library.
These default implementations depend on :hackney
and Jason
. Having learned about optional dependencies, they seemed like exactly what I was looking for (docs):
:optional
- marks the dependency as optional. In such cases, the current project will always include the optional dependency but any other project that depends on the current project won’t be forced to use the optional dependency. However, if the other project includes the optional dependency on its own, the requirements and options specified here will also be applied.
(The file is here if you want to poke around.)
If I change
defp deps do
[
{:hackney, "~> 1.14", only: [:dev, :test]},
{:jason, "~> 1.1", only: [:dev, :test]},
...
]
end
to
defp deps do
[
{:hackney, "~> 1.14", optional: true},
{:jason, "~> 1.1", optional: true},
...
]
end
I get strange results. First, dialyzer
(used via dialyxir
) no longer runs successfully and I get these errors:
:0:unknown_function
Function Jason.decode/1 does not exist.
________________________________________________________________________________
:0:unknown_function
Function Jason.encode/2 does not exist.
________________________________________________________________________________
:0:unknown_function
Function :hackney.body/1 does not exist.
________________________________________________________________________________
:0:unknown_function
Function :hackney.request/5 does not exist.
________________________________________________________________________________
done (warnings were emitted)
Then, 2 tests using hackney fail, although others tests also using hackney still pass. The tests failing are these.
What’s going on?
Per my understanding of the docs, using an optional
dependency shouldn’t change any of these results since the dependencies would be included in my project. They simply wouldn’t be forced on the users of my package, and would only make the version requirements apply if those dependencies were already included in their own project’s mix file.