962 karma · joined July 3, 2018
But because it would still be joining a bunch of strings together, it's literally about the same speed as the current implementation (which just adds the whole tree to a single array and joins it only once), so there's no real gain there.
And we lose script/style/tag hoisting, which is necessary for components to work the way they do, unless the JSX system is hacked in another (less simple) way to allow for it than currently.
1. It's hyper-efficient with how it reloads modules, to do the absolutely least amount of work necessary. If a file hasn't changed, it's not touched. If a .ts/.tsx file hasn't changed and nothing depends on it, its exports aren't touched. If it hasn't changed but something has that depend son it, it's function isn't recompiled, only its exports are re-exported by re-running it.
2. Everything in src/ is normal, but everything under site/ is loaded by src/ and compiled via sucrase, and run in its own runtime. This is what allows the psuedo module system above to be so efficient. It's also what makes the JSX feature so simple and yet fast.
3. The JSX syntax essentially compiles down to an object like {tag:string, attrs:object, children:any[]}, which can be manipulated at runtime. This allows for script/style/link hoisting and de-duplicating, which means you can put a css link in a component that's used multiple times in the site, but only loaded in the HTML once, and pulled up into the head element. It's turned into a string by walking the tree and adding to an array and joining it when done. I think it can be improved. For a while it was in the site/ runtime but I saw no benefit to that.
4. Import just uses require under the hood, and importing any file claims a dependency on it which reloads your file whenever the depended-upon file changes, whether the one you're importing is a normal ts/tsx module or a resource file (css, js, jpg, etc).
5. Importing a file tree returns a list of every file under that tree recursively, including future dependencies. So if you `import files from './images/';` then it will reload the file containing this import not only when a file changes in ./images/foo/bar/ but also when one is added or removed from it. This is really helpful in reloading when e.g. new data files are added. And the fact that it returns a flat list of "absolute" file paths (relative to site/) makes it easy to operate on and filter through.
6. When you import a static resource (jpg, css, etc), it returns {path:string, content:Buffer} as well as claiming a dependency on it, so that you can e.g. use the path in a href, or examine its buffer and do something with it, etc. Eventually I want to reintroduce the concept of dynamically generated routes, e.g. given a font dir, you can currently use the Font component, but it genereates a script tag; it'd be better if it introduced a link tag that can be cached by the browser.
7. Components with this are super cool and easy to use, but there's a lot of low-hanging fruit. I'm in no rush to see what kind of things I can do with it, but it's already picking up speed in the past few weeks. One of my next challenges for myself is figuring out how to use the dynamic static resource concept in point 6 to generate unique IDs for pseudo-scoped-css, similar to what react styled-components and all them did.
[1]: immaculatalibrary.com
[2]: @gen.z.bible.stories
The most direct problem is styling issues. Cross-component CSS in either direction has some serious limitations. I've written a little bit about it[1] in my blog but the short version is that there are some things that simply become absolutely impossible when using web components.
My main other gripe with them is the need for a build phase. The nature of WC almost begs for them to eventually become zero-build-time, but right now this just isn't practical. It requires too much boilerplate in every .html file (utf8 is broken on my site), the syntax isn't natively there even with tagged template literals, and there's no concept of data-list-fetching or data-based file generation.
There's a branch on my personal website[2] where I tried to start using web components, and it was so problematic that I long abandoned it.
Overall, I abandoned web components entirely in favor of making my own customized JSX-based SSG from scratch[3] which solves the same problems Lit, Next.js, et al. are intended to solve, but in a completely different way: using components for convenience, conciseness, and reusability, but only at the build-phase time. So far it's a well kept secret, which is probably good since it's been evolving so quickly that I wouldn't have been happy with any iteration being widely adopted so far. (Though I think this morning I finished off most of what I was unhappy with.)
[1]: https://sdegutis.github.io/articles/2023-08-07-modern-90s-we...
[2]: https://github.com/sdegutis/immaculatalibrary.com/tree/reset...
Honestly when this is the biggest problem you face on a daily basis, your life must be relatively easy.
> Well, no. The reality is that as applications grow in complexity, figuring out which values are reactive and which aren't can get tricky.
People keep re-learning that there's a certain amount of context that needs to be explicit, and you can't just imply everything. Just like when ruby and python made the mistake of getting rid of let/contst/var/etc and programmers said wait no that's a bad idea, now it just makes everyone's job harder, because neither the compiler nor the developer can figure out what context something belongs to.
In other words, there are serious drawbacks to using macros that are usually outweigh any benefits they might give you.
Seems like they can afford it.
I always think this is a funny way to word it. I mean, you're going to die either way. At the most, stopping using them might push it back further. But a car crash might even the playing field too. I think implicitly accepting language like this often indicates that a person isn't accepting the fact of the bigger picture.
The best code is the code that also doesn't make it harder to continue to get the job done.