adamu

adamu

Getting LiveView working with --no-assets

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?

Most Liked

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

Last Post!

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

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

Other popular topics Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement