veggiedefender / hn-friends

Highlight and tag your friends on Hacker News
48 stars 3 forks source link

Consider using a templating library #4

Open veggiedefender opened 6 years ago

veggiedefender commented 6 years ago

I'm currently manually writing a ton of DOM operations that are a pain to write and read.

kingdonb commented 6 years ago

How do you feel about JSX?

Below is what I do and what that looks like, and it's not that bad... but slightly shudder-inducing. JSX is basically the same thing minus the shudder-inducing:

$('main.site-content').prepend(
  $(`
    <div data-alert class="alert-box success radius" style="margin-top: 1rem;" id="job-change-update-alert-box">
      The operation was a success! <a href="#" class="close">&times;</a>
    </div>`
  )
);

I'm not suggesting that (you probably want to avoid writing plaintext HTML into multi-line strings, and you probably don't want jQuery either)

This looks pretty alright though by comparison, doesn't it?

document.getElementsByClassName('main', 'site-content').prepend(
  <div data-alert class="alert-box success radius" style="margin-top: 1rem;" id="job-change-update-alert-box">
    The operation was a success! <a href="#" class="close">&times;</a>
  </div>
);

I also have no idea if that's an example of non-idiomatic JSX, or even if that is error-free syntax, but I'm reading your code and trying to follow your example... so maybe if there are parts you don't like I can try to help you decide how to make them better, too!

veggiedefender commented 6 years ago

I love JSX and React and would want to use it, but I'm not too keen on bringing in a big dependency or extra build step. I might look into web components.

I'm a huge fan of being able to easily audit what's going on inside an extension due to their scary permissions, and code that goes through babel/webpack is generally hard to read. Being open source does help with this, but having to set up a build environment just to verify that an artifact does what it says is a pain in the ass.

I like and would go with your multi-line string trick, but almost every element in hn-friends has some sort of event listener attached or contains user-supplied text, which are two points where the approach breaks down.

kingdonb commented 6 years ago

So, if you want a vanilla templating library, there's also mustache.js

I'm not sure how it breaks down to attach event listeners to nodes the way I'm doing it. The node can be intercepted before it is passed from JQuery to prepend/append/etc. You can get a handle on the element, just like if you used document.createElement.

But if you're not using JQuery, I don't even know how you put that on the DOM tbh. (That's probably what you mean...)

veggiedefender commented 6 years ago

There are lots of jquery-less ways to do it like Range.createContextualFragment(), insertAdjacentHTML(), innerHTML, or DOMParser.parseFromString().

But my issue would be in attaching event listeners to multiple children, just one of multiple children, or deeper nested children, while I only have a handle on the parent. It's still doable but less than clean.

I'll look at mustache.

kingdonb commented 6 years ago

Not sure if you've seen Stimulus already, but they've just put out their 1.1.0 release and it seems like it could make a lot of those operations easier to write and easier to follow:

https://stimulusjs.org/

The module is about 60KB or ~12KB gzipped

You are meant to use this to set up and attach controller functions to event listeners via simple data-action attribute syntax and bind your JS function controllers to data targets...

I had been waiting a bit to see if this matures before I put it anywhere important, I think it looks pretty good. Seems like code you produce this way would be very easy to follow and easily audit-able. The one thing it doesn't really do is actually generating HTML elements from data structures, but you can do a lot with data-target as they show it being used with JavaScript's built-in Template Literals:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

attaching event listeners to multiple children, just one of multiple children, or deeper nested children, while I only have a handle on the parent

I'm still trying to parse out exactly what you mean by this, but thanks again for sharing and publishing the extension; I'm hoping to put together basic proof-of-concept for my own Pivotal Tracker extension this weekend, that puts some extra buttons onto Pivotal cards to help manage associated Pull Requests and CI checks, and I think I'm going to try out this approach with Stimulus.

kingdonb commented 6 years ago

There's also preact which is supposed to be only 4kb