Weekend with AlpineJS

Just like I did one on Tailwind some time ago, I am going to play with AlpineJS the next few days. It’s a nice little JS framework that stays out of your way and lets you sprinkle in some reactivity as needed- you get to keep your DOM to yourself. It is the “A” of PETAL stack. I didn’t really enjoy the “T” of PETAL, not any fault of “T” but my personal choice. I have never even scratched a line of AlpineJS yet so it would be cool to see how it fits my brains.

As with my other journals, I’ll just speak with myself as I progress through things. My reference will still be the Covid19 Dashboard (it’s like the only open source live view project I have).

I’ll document my learning, pain-points, awe(some|ful) moments here along with screenshots and stuff! Just pushed the branch hello-alpine! Let’s get started :smiley:

5 Likes

Corresponding tweet for this thread:

Share link for this tweet.

1 Like

Another one I will be interested in reading Mafina!! Keep up the good work - you are an inspiration - I can’t wait to get back into reading mysef! :+1:

2 Likes

Started some time ago… Mostly involved fighting with errors. Setting it up following the tutorials given in the web (as in Phoenix LiveView + Alpine ones) don’t apply since I need to do an Alping.start() before the app (which was mentioned in their docs Migrating from V2 section. And npm install alpinejs doesn’t seem to work (They DID mention building from source with npm build... but I felt like following common sense at first try). Alpine 2.0 works though but I’m more interested in the cutting edge, after all, it’s a pet project and free learning.

Googling for the error messages I had “Webpack … appropriate loader… something…” sent me to Github discussions that led to 404. I thought that sucked. Especially when the discussions surrounding those links seemed helpful and results of those discussions weren’t documented any place else.

Anyways, it’s barely been ~30 minutes or so, I’d not start ranting right now. Though it led me to some really interesting frameworks like Stimulus and Unpoly.

2 Likes

Not going to spend time with v3 for now, got back to v2 into the well-documented land. My focus right now is to learn, will work harder and document things in the next phase, if there is any.

So far, getting LiveView to play well with Alpine was easy. Just do a npm install alpinejs@2.3.4, make your app.js look more like the following:

// ... SNIP ...
import Alpine from "alpinejs";

Alpine.start();
window.Alpine = Alpine;

// ... SNIP ...

let liveSocket = new LiveSocket("/live", Socket, {
  // ... SNIP ...
  dom: {
    onBeforeElUpdated(from, to){
      if(from.__x){ window.Alpine.clone(from.__x, to) }
    }
  }
});
// ... SNIPING CONTINUES ...

It seems to work without the Alpine.start() and window.Alpine = Alpine lines, though you would have to change window.Alpine.clone into Alpine.clone in the other line if you don’t put it on window.

As a test, I just randomly put a <div x-data={ counter: 0 }><button x-on:click="counter += 100">INCR</button><div x-text="x" /></div> in my code and clicked to see the counter increasing.

However, these things won’t work in SurfaceUI component. For good reasons too. But if needed (I may not), I will just put a custom attribute like when_alpine_clicked and set my logic there and add a <div x-on:click={{@when_alpine_click}}>...</div>. Though I don’t think I’ll do that.

Discussion on it is around here.

I haven’t work with it yet but there is a situation of <template> conflict between surface and Alpine that can be dealt with <#Raw> tags surrounding the Alpine version. Discussions that helped me on this are here.

I think I did the set-up. Will not move over and do something useful with this! Commits are in this branch.

2 Likes

Okay, I am going to have to kill this branch from the dashboard. Looks like I have little need to apply any client-side JS on this one. No need to invent problems if things are going great without the solution you have in mind :wink:

However, there’s another app I have in mind, a project I’ve wanted to work on for awhile now, “Miles to go…” a ride tracking app. You install the app, hook it up with the server, and wherever you go via bike, car, swim or run, you get the location data and reports in the app, log in and get it. I’m thinking of starting biking, so I’ll use it for personal use.

Maybe I’ll use it there instead.

2 Likes

What AlpineJS? The weekend was spent with me cursing Webpack. Loudly when my kid was outside. While webpack had problems with Alpine 3 (not sure if it was me or not but installations should be idiot-proof in this day and age so even if I’m an idiot, I shouldn’t have suffered). Then I looked into webpack a little and found out, it’s not fun. So I decided to just remove it and get this thing called “Parcel”. And everything works. From now on, the first thing I do after starting a Phoenix project (that needs a front-end) is, replace Webpack with Parcel.

Quite simple really:

  1. The most satisfying thing! Remove Webpack, delete the webpack.config.js, rejoice.
  2. npm install --save-dev parcel parcel-plugin-stdin sass (Not node-sass).
  3. Make your “scripts” in package.json look like the following:
  "scripts": {
    "deploy": "cp -R static/* ../priv/static/ && parcel build js/app.js --dist-dir ../priv/static/dist --public-url /dist --no-cache",
    "watch": "cp -R static/* ../priv/static/ && parcel watch js/app.js --dist-dir ../priv/static/dist --public-url /dist"
  },

watch out though, depending on your Parcel version, it could be --out-dir or --dist-dir (In example above).

  1. Get a .sassrc and add {"includePaths": ["node_modules"]} if you’re using SASS
  2. Update endpoint.ex by adding a dist in Plug.Static-s only: list
  3. In dev.exs config for YourApp.Endpoint should have watchers: [npm: ["run", "watch", cd: Path.expand("../assets", __DIR__)]] as watcher!

So far it’s working nicely. I can totally run with Alpine 3, and also, no Webpack. If anything, I’d have the biggest learning of this weekend as getting introduced to Parcel.

2 Likes

:rofl:

Might be worth doing a blog post about that Mafinar? :smiley:

1 Like

Too late for that. I have decided to rid JS entirely for this project. I’ve had it, since LiveView helped me not write as much JS as I normally would, why not take it to the next level and write my hooks in a non-js language as well?

I am experimenting with ClojureScript at the moment. I have a few hooks, charts and maps. So this should be a good story if I can get it done in ha a day (I haven’t done any meaningful Clojure for more than half a decade)

3 Likes

Damn it worked! Sorry I gotta postpone this thread. Just wrote my first phx-hook with ClojureScript. Three more to go! :heart:

Will share the code once I’m done, looks like I will be in an hour max.

3 Likes

Wait what huh? Are you using ClojureScript with Reagent? And therefore… React? ClojureScript with LiveView does sound like great fun.

3 Likes

No Reagent/React. I am just using ClojureScript for LiveView hooks. Also deleted JS build tools in favor of shadow-cljs. Well to be honest, there’s a little bit Parcel left but that’s only for sass stuff which I’ll take care of next week. In fact node-sass and sass-loader is what triggered me in the first place.

I admit the ClojureScript isn’t as idiomatic as I’d like it to be and I never got to use Shadow Cljs so its configuration is pretty basic. My main goal was to see if I can do hooks with it and set it up in a Phoenix system and that seemed to work. I’ll let experience teach me now.

Oh, and here’s the code: Hello clojurescript by code-shoily · Pull Request #21 · code-shoily/covid19 · GitHub

I will write a blog post on it soon! :smiley:

Never expected to write Clojure when I started this thread.

3 Likes

Love AlpinejS
It’s really very light and robust.
Recent discovery I can just add the whole lib inline on page and have a huge boost in webvirals performance.

Curious to hear your feedback …

1 Like