Livereload stops working when importing Elm bundle

Hi,

I’m using phoenix 1.7 and trying to integrate my Elm front end with live reloading in the development setup. Starting from a fresh a phoenix project, I added import "./elm.js" to my app.js. In addition, I have a build.js file that bundles my Elm code using esbuild.

Whenever I modify my Elm code, I see the building of my Elm code taking place in the console. But the live reloading stops working if I import my elm.js in app.js. I still see the rebuilding taking place in the console, but the browser just doesn’t reload.

Would be great if someone has an idea on what I’m doing wrong here.

app.js

import "phoenix_html"
// Establish Phoenix Socket and LiveView configuration.
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
//import topbar from "../vendor/topbar"
// Import the compiled Elm app:
import "./elm.js"

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})

// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())

// connect if there are any LiveViews on the page
liveSocket.connect()

// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000)  // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket

build.js

const esbuild = require('esbuild');
const ElmPlugin = require('esbuild-plugin-elm');

async function watch() {
  const ctx = await esbuild.context({
    entryPoints: ['src/index.js'],
    bundle: true,
    outfile: '../js/elm.js',
    plugins: [
      ElmPlugin({
        debug: true,
        clearOnWatch: true
      }),
    ],
  }).catch(_e => process.exit(1))
  await ctx.watch()

  console.log("done")
}
watch()

dev.exs watchers

node: ["./build.js", cd: Path.expand("../assets/elm", __DIR__)]

Best regards
Max

I’d give the approach outlined in this Phoenix Elm Starter repo a try. At a glance, the build.js in particular takes a different approach.

esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  outdir: '../js',
  watch: process.argv.includes('--watch'),
  plugins: [
    ElmPlugin({
      debug: true,
      clearOnWatch: true,
    }),
  ],
}).catch(_e => process.exit(1))

good point, I actually started with this exact starter repo, which currently doesn’t work properly due to the fact that esbuild 0.17.0 doesn’t support a watch flag anymore

my build.js uses an updated configuration to work with esbuild 0.17.0, which turns out be working fine