Iβm fighting against a mess of compile dependencies.
One issue is that many things have a runtime dependency on the router (ok) and that the router has multiple compile-time dependencies on views and layouts (not ok).
# router.ex
# introduces a compile-time dependency
pipeline :example do
plug(:put_layout, {MyApp.LayoutView, :example})
end
# no dependency
pipeline :example do
plug(:put_layout, {Module.concat(:MyApp, :LayoutView), :example})
end
Is this expected / am I missing something?
Before I write a macro to do this, is there a better way to resolve this?
I was naively thinking that this pattern was pretty natural and would be handled properly, either by put_layout accepting a string for the module name, or by plug being a smart macro that could avoid the compile-time dependency altogether, or by pipelines being in a different files from routes for example.
One issue is that many things have a runtime dependency on the router (ok) and that the router has multiple compile-time dependencies on views and layouts (not ok).
The combination of:
Elixir v1.11 (separately tracks imports so these donβt become compile-time deps)
explicit router helper aliases (ditto; also thanks to 1. should be less of an issue in general)
should hopefully have alleviated those issues. Have you already tried all three? If not, did it help at all?
plug_init_mode is only added to config/dev.exs by default which means when running tests weβd potentially have more recompilations than in dev, perhaps we should be adding it to test.exs too, not sure.
plug_init_mode is set to :runtime in dev mode (and I wish I knew if it could be in test mode).
probably not using explicit router help aliases. We probably should do that to avoid some recompilation when we change routes, but my understanding though is that there is no fundamental reason for the router to have a compile-time dependency on these layouts, right?
That mix xref graph --source lib/app_web/router.ex --label compile has refs to lib/app_web/plugs/ is fine, but lib/app_web/views/ is not.