In a relatively small project (~243 files), changing a single line in a live view template
.leex (colocated with an
.ex file, so I guess it’s inserted in place of the
render/1 function) causes 42 files (including the ones in app “contexts”) to be recompiled and prevents fast, iterative development. I’ve read that it could be due to phoenix router macros (but I’m I don’t know what to do with that info), what are other possible culprits, has anyone succeeded in reducing the number of files that get recompiled to 1, the template?
Is there maybe something like
mix compile --trace to list the modules that are being compiled because of a change? And maybe there is some command to get the cause for why the files are being recompiled?
MIX_DEBUG=1 mix compile, but it doesn’t show the files being recompiled. Could
mix xref be used somehow?
fswatch _build -r | cat | grep .beam, and I see all live views being recompiled for a change in one of them …
The cause seems to be a
sidebar.ex component that references many other liveviews.
mix xref graph --label compile to check what modules depends on it during compilation.
Strange thing that nothing is returned for
--label compile, maybe there are some implicit dependencies.
This sounds like a cross-module compilation dependency issue, which I wrote about for Changelog.
tldr: you are probably importing one or more custom modules into other modules. to prevent this issue, alias those modules instead. @wojtekmach wrote a useful script to help convert imports to aliases
Thank you! Seems like I did a really bad job at searching for similar issues since I missed quite a few relevant articles.
I’ll make sure to read them tomorrow, but for now, just based on your tl;dr:
The main cause for my particular problem with liveviews was sidebar and navbar components that were defined in layout view (
templates/layout/...) and then used in many other views which caused cyclical dependency across almost all live views (
layoutview (live.html.leex) -> some live view -> layoutview (sidebar or navbar)) so a change in any liveview caused recompilation of the layoutview which then caused the recompilation of all the other live views. The fix was to move these components (sidebar, navbar) to their own views (or use inline/collocated templates) and then render them in each custom live view layout defined in separate view modules. Not ideal and quite repetitive, but seems to work for now or until I find a way to make
render_layout/4 work with live components..
The other cause that I found today are module names in
Routes.live_path functions like
Routes.live_path(@socket, AppWeb.SensorLive). Seemingly harmless, these functions were responsible for ~100 unnecessary recompilations. The fix is to completely remove
live_path calls from the app and use https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.Router.html?#live/4-actions-and-live-navigation instead.
dev env seems also to have caused unnecessary recompilations.