Lately I've been developing with a JS workflow that's finally made me think "hey this is fun!" again:
Chrome target, native ESM modules, VS Code with JSDoc annotations for types. All libraries (chosen preferentially from microjs.com) are copied into vendor/, and the front end is written in preact.js using htm [0] for native JS tagged html strings, leading to code like:
import ImageView from "./image-view.js";
render({ trail_item, selector }, state) {
/** @type {LinkItem} */
let link_item = trail_item;
let title = this.render_title(trail_item);
let favicon = this.render_favicon(trail_item);
let img = html`<ImageView src=${favicon} />`;
return html`${img}${title}`;
}
There's a VS Code extension which formats html`` strings as actual HTML, and the Typescript checker built in to VS Code gives me advanced types and autocomplete, all with a workflow that's as simple as "refresh page".
Granted, not every project can afford to target just evergreen browsers, but for my use case it works perfectly and I finally feel like I have the perfect blend of old-style web dev (in terms of refresh cycle) with modern language features and typing. The overhead, both in page-weight and cognitive load, is as small as I can make it.
EDIT: Modified my code sample to show how you can use Preact components in a JSX-like way.
[0] https://preactjs.com/guide/v10/getting-started/#alternatives...