Elixir 脚本递归加载文件夹中的所有模块
Elixir script load all modules in folder recursivelly
我想在特定文件夹中递归地编译和加载所有模块。
我知道我可以用 Mix 项目做到这一点
iex -S mix run
这将加载 lib/
目录中的所有文件。
但是我希望在非 Mix 脚本中有相同的行为 - 如果可能的话以编程方式进行。
类似于 Code.compile_all("directory/")
有这样的API吗?
我不确定在 Elixir 中是否有内置的方法来执行此操作,但是您可以使用 Erlang 中的 filelib:fold_files/5
之类的方法来获得相同的结果。
:filelib.fold_files "directory/", "\.ex$", true, &Code.load_file/1, []
澄清一下: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 等等),你可以在 [=16] 中提供你想要混合的任何目录=]:
elixirc_paths: ["lib", "my/other/path"]
就是这样。
我想在特定文件夹中递归地编译和加载所有模块。 我知道我可以用 Mix 项目做到这一点
iex -S mix run
这将加载 lib/
目录中的所有文件。
但是我希望在非 Mix 脚本中有相同的行为 - 如果可能的话以编程方式进行。
类似于 Code.compile_all("directory/")
有这样的API吗?
我不确定在 Elixir 中是否有内置的方法来执行此操作,但是您可以使用 Erlang 中的 filelib:fold_files/5
之类的方法来获得相同的结果。
:filelib.fold_files "directory/", "\.ex$", true, &Code.load_file/1, []
澄清一下: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 等等),你可以在 [=16] 中提供你想要混合的任何目录=]:
elixirc_paths: ["lib", "my/other/path"]
就是这样。