Phoenix 1.6.0-rc.0 released!

In the upgrade instructions, it says

Phoenix’s watchers configuration is build-tool agnostic, so you may continue to enjoy your existing webpack configurations generated by phoenix 1.5 or earlier.

But after updating the deps and switching to .html.heex, my JS hooks no longer work, and I get this error in the console:

Uncaught TypeError: phoenix_live_view__WEBPACK_IMPORTED_MODULE_4__.LiveSocket is not a constructor
    at eval (app.js?7473:41)
    at Module../js/app.js (app.js:142)
    at __webpack_require__ (app.js:20)
    at Object.0 (app.js:164)
    at __webpack_require__ (app.js:20)
    at app.js:84
    at app.js:87

EDIT: solved, see below

1 Like

With phoenix 1.6 the exports of phoenix.js have changed (there’s no longer a default export iirc). You might need to update your app.js accordingly.

1 Like

I think the fix for the JS hooks might be as simple as:

npm i --prefix assets

because now everything is running smoothly for me on 1.6 + webpack

1 Like

The npm opt-in path with esbuild is great! You simply npm install when you want a node dep and that’s it! We generate this info in the top of everyone’s app.js:

// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
//     import "./vendor/some-package.js"
//
// Alternatively, you can `npm install some-package` and import
// them using a path starting with the package name:
//
//     import "some-package"
//
7 Likes

Phoenix.LiveView.Helpers.form/1, which is imported by default into your templates by way of your app_web.ex is what you want to use here. So update your heex template to:

<div class="flex mt-6 mb-8">
  <.form let={f}
      for={@changeset}
      phx_submit="move_items"
      phx_target={@myself}>
    <div>
      <%= select f, :category_id, @category_select, prompt: "Move to list" %>
      <%= submit "Move" %>
    </div>
  </.form>
</div>


4 Likes

Following the official upgrade guide, we create a new alias mix assets.deploy and it’s implied that we should be able to immediately run it. But I’ve noticed that there are a few additional steps required before the task will run successfully. And since I’ve seen a few comments asking about this issue, I decided to write a brief tutorial of these steps, in hopes that it might save a little time for those who encounter it:

Fixing esbuild errors when upgrading to Phoenix 1.6

1 Like

The only downside of the new liveview template format i see is added mental complexity (more special elements instead of single <%= %>)

I definitely do not want to see yet another “Angular.js LiveView Edition” in the future :wink:

What are your thoughts on the Surface’s approach?

Surface adds even more special syntax, so it could be more pleasant to write but also harder to understand. ~H adds only a few new idioms on top of ~L, which is good

My understanding was that the syntax replaces the <%= => syntax, so it’s more consistent with the {} attribute syntax.

<%= => is still there, depeding on purpose you need to choose correct one (between <., {, <%=). So “replaces” only in some cases

From the other thread:

In the near future, you will be able to use Surface components in ~H too but only after LV incorporates other core features from Surface’s component model, for instance, slots, which is already on the roadmap.

@chrismccord Is that roadmap publicly available? I’ve adopted Surface for a non-LiveView app and components are a game changer, but slots are the secret sauce.

I’ve written a few non-LiveView Surface components and never had to reach out for <%= yet. It might take some time to get used to <. syntax for function components. Surface’s module-based <Thing> is something that I’ve seen a lot in React, so it’s more “natural” on the eyes.

Here it is @stefanchrobot

2 Likes

Yes. That is some confusion. This is one area I felt Surface is more consistent with its syntax.
As of now, my feeling is - surface will always be HEEx@next using LiveView. Let us see how it goes.

Maybe I missed something, but I don’t understand one thing. In this example why there are no inner components like input/select/submit? For example (pseudosyntax):

<div class="flex mt-6 mb-8">
  <.form let={f}
      for={@changeset}
      phx_submit="move_items"
      phx_target={@myself}>
    <div>
      <.select for={f, :category_id, @category_select} prompt="Move to list"/>
      <.submit value="Move"/>
    </div>
  </.form>
</div>

It would be more readable. Will those helper components be included in future releases of phoenix?

I’d be curious about that as well. I recently talked to someone on slack who put a huge list into a select and wondered, why the options on select inputs weren’t granularly diff’ed.

The driving factor around {} for elixir within an HTML tag is eex is awkward when trying to handle attributes inside a tag, for example:

    <div id="<%= @id %>" class="<%= @class %>">
    vs
    <div id={@id} class={@class}>

It’s a tradeoff for learning, but this is exactly why we kept regular <%= %> EEx rules outside of HTML tags. I hope that give some insight. The syntax is a 1000% upgrade for me :slight_smile:

12 Likes

Agree. It is just that - as a developer - now I have to put up some elixir code in this template. Should I be using <%= %> or {} is a question that needs to be answered every time. Probably with some practice we do get there. But, that is what I understood out of @thousandsofthem comment. :slight_smile:

{} for HTML attributes, <%= %> for everything else :slight_smile:

7 Likes