adamu

adamu

I’m trying to build a project using phx.new’s --no-assets flag. I don’t want a frontend build step - only static JS and CSS files. I don’t want to use Tailwind or Esbuild dependencies, however I do want to use LiveView.

LiveView does not work out of the box with --no-assets, because the required setup is not placed into app.js by the generator. Here is the regular generated app.js, and the one for --no-assets. You can see that the 2nd one doesn’t perform the necessary LiveView setup.

If I generate a new phoenix project without --no-assets, compile the assets, and copy the generated app.js to my --no-assets project, LiveView works. But I want to get LiveView working with just static compile-time JS files, without a build step for the JS.

I have attempted to rebuild the app.js file myself, by manually coping the relevant JS files from the dependencies to /priv/static and altering the import statements to things like:

import { Socket } from "./phoenix.js" // not "phoenix"

The browser does load this file, but it generates this error:

The requested module ‘http://localhost:4000/assets/js/phoenix.js’ doesn’t provide an export named: ‘Socket’

Is there a way to get LiveView working out of the box with the distributed Javascript using only the browser? Or do I need to have at least some kind of step to compile the required ‘runtime’ Javascript?

First 3 of 3 Posts Switch mode

netoum

netoum

When you use the --no-assets option, the generator will create a default js in priv/static/js/app.js

It tells you to manually add theLive View JS

// For Phoenix.HTML support, including form and button helpers
// copy the following scripts into your javascript bundle:
// * deps/phoenix_html/priv/static/phoenix_html.js

// For Phoenix.Channels support, copy the following scripts
// into your javascript bundle:
// * deps/phoenix/priv/static/phoenix.js

// For Phoenix.LiveView support, copy the following scripts
// into your javascript bundle:
// * deps/phoenix_live_view/priv/static/phoenix_live_view.js

It also warns you to use it this way in the mix phx.new documentation

--no-esbuild - do not include esbuild dependencies and assets. We do not recommend setting this option, unless for API only applications, as doing so requires you to manually add and track JavaScript dependencies

I believe your goal is to use Live View without JS bundler
You can absolutely do it, the most direct but not recommended is (for learning purposes) :

  1. Copy deps/phoenix/priv/static/phoenix.js to you priv/static/js

  2. Edit your priv/static/js/app.js to add the following (no import needed)

const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
const liveSocket = new LiveView.LiveSocket("/live", Phoenix.Socket, {
  longPollFallbackMs: 2500,
  params: {_csrf_token: csrfToken}
})
liveSocket.connect()
window.liveSocket = liveSocket
  1. Add the following to your root.heex.html :
<script defer phx-track-static type="text/javascript" src={~p"/assets/js/phoenix_live_view.js"}>

However a better way is to use Plug.Static to fetch an updated minified version from the Live View deps

  1. Add the following to your `endpoint.ex
  plug Plug.Static,
    at: "/vendor/phoenix_live_view",
    from: {:phoenix_live_view, "priv/static"},
    only: ~w(phoenix_live_view.min.js),
    gzip: not code_reloading?
  1. Edit your priv/static/js/app.js to add the following (no import needed)
const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
const liveSocket = new LiveView.LiveSocket("/live", Phoenix.Socket, {
  longPollFallbackMs: 2500,
  params: {_csrf_token: csrfToken}
})
liveSocket.connect()
window.liveSocket = liveSocket
  1. Add the following to your root.heex.html :
<script phx-track-static type="text/javascript" src="/vendor/phoenix_live_view/phoenix_live_view.min.js"></script>

But once again the recommended approach is to use the --asset option (by default) of mix phx.new

Hope this helps

adamu

adamu OP

Thank you for the response!

The suggestion to use the fully-qualified module names worked, thank you!

The other requirement was that app.js needs to come after the includes to the phoenix scripts in root.html.heex:

<script defer phx-track-static type="text/javascript" src={~p"/assets/js/phoenix.js"} />
<script defer phx-track-static type="text/javascript" src={~p"/assets/js/phoenix_html.js"} />
<script defer phx-track-static type="text/javascript" src={~p"/assets/js/phoenix_live_view.js"} />
<script defer phx-track-static type="text/javascript" src={~p"/assets/js/app.js"} />

Do you have any idea why the import statement was not working, even though the browser could load the script? Perhaps that only works with esbuild, not when running directly in the browser?

netoum

netoum

“To import or not to import, this is the question” :laughing:
Javascript has different module formats and each require different type of setup and imports

Phoenix JS is exported in the following formats: ESM, CJS and IIFE.
https://github.com/phoenixframework/phoenix/blob/main/config/config.exs
You can use any depending on your needs

A possible reason the import statement is not working is that your script is not loaded as a module.
Try adding `type=“module” to your script import

You can read more about Javascript modules history and differences
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

The general advise it to use ESM whenever possible as it offers the latest and more complete features

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
rahultumpala
Hello, I have an Elixir backend that implements a custom protocol over TCP. I want to load test the backend and assess the performance o...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement