I want to compile and load all modules recursivelly in specific folder. I know I can do this with Mix project
iex -S mix run
Which will load all files in lib/
directory.
However I want the same behaviour in non-Mix script - programmaticly if it's possible.
Something like Code.compile_all("directory/")
Is there any API like that?
Just to clarify the terms: Mix does not load the files in lib/, it compiles them if needed, and then uses the compiled byte code (without having to execute the whole file again).
You can load any file in a directory by calling Code.require_file/1
or Code.load_file/1
but that does not generate any artifact in disk. If later on you call Code.require_file/1
, the same files will be evaluated again, which may take time. The idea of compiling is exactly so you don't pay this price every time.
That said, let's answer your question directly.
A way to load everything in a directory is:
dir
|> Path.join("**/*.exs")
|> Path.wildcard()
|> Enum.map(&Code.require_file/1)
If you want to compile them, use:
dir
|> Path.join("**/*.ex")
|> Path.wildcard()
|> Kernel.ParallelCompiler.files_to_path("path/for/beam/files")
If you want to just compile another directory in the context of a project (with a mix.exs and what not), you can give any directory you want to Mix inside def project
:
elixirc_paths: ["lib", "my/other/path"]
That's it.
I'm not sure about built-in ways to do this in Elixir, but you could achieve the same result using something like filelib:fold_files/5
from Erlang.
:filelib.fold_files "directory/", "\.ex$", true, &Code.load_file/1, []
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