我想在特定文件夾中遞歸編譯和加載所有模塊。 我知道我可以混合項目Elixir腳本遞歸地加載文件夾中的所有模塊
iex -S mix run
將加載在lib/
目錄中的所有文件做到這一點。
但是我想在非Mix腳本中使用相同的行爲 - 如果可能的話,請使用編程方式。 類似於Code.compile_all("directory/")
是否有像這樣的API?
我想在特定文件夾中遞歸編譯和加載所有模塊。 我知道我可以混合項目Elixir腳本遞歸地加載文件夾中的所有模塊
iex -S mix run
將加載在lib/
目錄中的所有文件做到這一點。
但是我想在非Mix腳本中使用相同的行爲 - 如果可能的話,請使用編程方式。 類似於Code.compile_all("directory/")
是否有像這樣的API?
只是爲了澄清條款:混合不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"]
就是這樣。
我不確定內置的方法可以在Elixir中做到這一點,但您可以使用類似Erlang的filelib:fold_files/5
這樣的結果來獲得相同的結果。
:filelib.fold_files "directory/", "\.ex$", true, &Code.load_file/1, []
謝謝@Jose。我看到你甚至沒有睡覺只是爲了幫助你的社區:) –
謝謝何塞!這節省了我的培根。 – localshred
嘿@Jose我已經嘗試了在Phoenix項目的'mix.exs'中使用方法#3來加載'lib'文件夾(例如'lib/new_namespace')中的目錄。但是,Elixir似乎沒有加載/編譯我在該文件夾中定義的模塊。我收到一條錯誤消息:**(UndefinedFunctionError)函數NewNamespace.ModuleName.test/0未定義(模塊NewNamespace.ModuleName不可用) NewNamespace.ModuleName.test()'。我想知道你是否可以指出如何解決這個問題的正確方向,正確的方法。我一直在使用'Code.require_file',但這似乎是錯誤的做法 – John