我想在特定文件夹中递归编译和加载所有模块。 我知道我可以用Mix项目
来做到这一点iex -S mix run
将加载lib/
目录中的所有文件。
但是,我想在非混合脚本中使用相同的行为 - 如果可能的话,以编程方式进行。
类似Code.compile_all("directory/")
的东西
有这样的API吗?
答案 0 :(得分:31)
只是为了澄清术语:Mix不加载lib /中的文件,如果需要它会编译它们,然后使用编译的字节代码(不必再次执行整个文件)。
您可以通过调用Code.require_file/1
或Code.load_file/1
来加载目录中的任何文件,但这不会在磁盘中生成任何工件。如果稍后调用Code.require_file/1
,将再次评估相同的文件,这可能需要一些时间。编译的想法完全是你每次都不付这个价格。
那就是说,让我们直接回答你的问题。
在目录中加载所有内容的方法是:
dir
|> Path.join("**/*.exs")
|> Path.wildcard()
|> Enum.map(&Code.require_file/1)
如果要编译它们,请使用:
dir
|> Path.join("**/*.ex")
|> Path.wildcard()
|> Kernel.ParallelCompiler.files_to_path("path/for/beam/files")
如果您只想在项目的上下文中编译另一个目录(使用mix.exs而不是),您可以在def project
内提供要混合的任何目录:
elixirc_paths: ["lib", "my/other/path"]
就是这样。
答案 1 :(得分:1)
我不确定在Elixir中执行此操作的内置方法,但您可以使用Erlang中的filelib:fold_files/5
之类的内容获得相同的结果。
:filelib.fold_files "directory/", "\.ex$", true, &Code.load_file/1, []