Mix compiler that bundles external-module JavaScript hooks for the host app.
A LiveView JS hook must be present in the host's single LiveSocket at
construction time — a nested LiveView cannot register one at runtime. Modules
declare their prebuilt hook bundles via js_sources/0 (see PhoenixKit.Module);
this compiler discovers them and writes one aggregate file the host loads with a
single <script> tag (added once by mix phoenix_kit.install).
What it does (every compile)
- Discovers external modules via
PhoenixKit.ModuleDiscovery, collects theirjs_sources/0entries. - Resolves each bundle's absolute path via
:code.priv_dir/1— so it works for Hex installs and path deps alike, with nodeps/<app>path arithmetic. - Concatenates the bundles (each wrapped in an IIFE so their top-level scopes
can't collide) into
priv/static/assets/vendor/phoenix_kit_modules.js, followed by a merge that folds each bundle'swindow.<Global>intowindow.PhoenixKitHooks(which the host already spreads intoLiveSocket). - Writes only when the content changed (diff-before-write) to avoid live-reload thrash.
The output tag is stable: adding or removing a JS-bearing module only changes
this file's content on the next compile — never the host's layout — so it stays
zero-config like css_sources/0.
Setup (one-time, by mix phoenix_kit.install)
# mix.exs
compilers: [:phoenix_kit_js_sources, :phoenix_live_view] ++ Mix.compilers()
# root.html.heex, before app.js
<script src={~p"/assets/vendor/phoenix_kit_modules.js"}></script>Failures are loud: a declared bundle that can't be resolved raises a compile error rather than silently shipping a chart with "unknown hook" console errors.