Implementing single-file web components
ckeditor.com
ckeditor.com
This has resulted in our newer lit-html and LitElement libraries, where the DOM rendering is done in JavaScript, but it's still possible to do single-file style:
import {LitElement, css, html} from 'lit-element';
export class MyElement {
static styles = `
:host {
display: block;
background: red;
}
`;
static properties = {
name: {},
};
render() {
return html`
<h1>Hello ${this.name}</h1>
`;
}
}
customElements.define('my-element', MyElement);
There are a number of reasons why this is better, IMO. Not requiring any builds and utilizing the JS module graph are big ones.The most important though is that the essential job of templates is to interpolate data into DOM. It's much easier this by building DOM in JS, than by trying to access and transform data in HTML.
Templates need some kind of expression language. If the template is in HTML then you need to invent expression delimiters, the expression syntax and semantics, and a way to get data into HTML: HTML doesn't natively have a way to refer to JavaScript objects. This is all custom, needs code to implement, and you need to train developers on it.
On the other hand if you write templates in JS you can take advantage of full JavaScript expressions, imports, and natural lexical scoping... and the data is typically already in JavaScript.
As a non-programmer (UX), I used to watch Polymer with so much interest, since it had HTML tag-like syntax. I copy paste component codes & construct an UI. There was simplicity in <googlemaps lat="89.2" long="123.2" draggable="false"></googlemaps>
Now with lit-html, it went from unique HTML/WebComponent for non-coders, to another one of the JS frameworks out there.
If <google-maps> was rewritten in LitElement, you'd still be able to write:
<google-maps lat="89.2" long="123.2" draggable="false"></google-maps>Unfortunately this breaks down as soon as you start to break up the page into sections (you end up with a component that needs a "layout" to provide surrounding <html><body>(...) etc).
Ironically, now with html5 being rather loose and fast, you might actually get a decent preview of such a widget again... But it's still not right for "web applications" as opposed to "hypertext applications".
Full applications need full gui widgets - and html isn't a good fit.
I think one difference between lit-html and React/other JS frameworks is that lit-html knows which portions of its template are static, and can avoid reconciling static portions. This is the same optimization as what Svelte can do, but without the need to change your toolchain.
Disclaimer: I work at Google, but on a completely unrelated team.
But having separate style-sheets, I don't know. I have done Vue with SASS etc, but the abstraction I felt was a bit too vague. At least our team got a little lazy and wrote massive style sheets with nested classes, and similarly we then ended up fitting too much HTML to the template.
With JSX/TSX I can keep myself from doing those mistakes, and just make small simple components, that do not go overboard with logic. Although I have to say performance-wise React is still very much pain in the ass to debug, and I can't say how many working days I have wasted on some dumb rendering bug, where the components would rerender constantly.
And it's way, way too hard to find those problems and I think this is the weak point of React. No one likes figuring out how to performance optimize a simple list. It should work straight out-of-the-box! I hope that Polymer team will try to make their framework a little better than React on this part.
A colleague of mine went with Polymer for a prototype (against my advice), and switched to Angular within 2 weeks because the performance of Polymer was so bad. I think the web-component approach is inherently inefficient for large apps, because you can't batch DOM reads and write like the other frameworks do.
Were you using CSS modules with your SASS? I've found a few base styles in global SASS along with scoped styles in CSS (SASS) modules works pretty well for keeping things simple.
But Polymer isn't our current generation library anymore. LitElement, which is based on the lit-html template library, is. LitElement measures clearly faster than Angular and React on shootouts.
There's nothing inherently inefficient about web components, and we do batching of DOM updates much like frameworks. LitElement is even able to yield between different component renders naturally, like React concurrent mode, to not jank the page.
EDIT: I was looking at the wrong. I see, it seems like a nifty way to combine styles. But hmm, I guess this one of those things that what works for you, is good enough.
Somehow keeping the styles in the same file, inside the styled components, just makes everything easier to me. Granted the string interpolation is bit annoying at times for accessing the theme variables but ehh.
That being said, if it's all in a single file, you can copy and paste that file into your project and then modify the thing, unless the single file is itself a bundle.
At my last company we tried to make a button component. But then we wanted to be able to change url with it. But then if you ctrl-click, it should open in a new tab. And then there were certain styles of button, with mixed and matched shapes.
Nowadays, I see components as single use, or specific to a project. And for anything that's more about a visual than a function (ie buttons), just use css classes and implement the underlying Elements from scratch.
Point being, everyone wishes they could model the perfect abstraction of a component, but then you start adding config to make it do everything until it's basically its own miniature programming language (with worse docs).
Anytime I need to do some real work on this project, it's easier to just replace the call site of the component with the final HTML output, and move any required logic to the top level.
Turns out that across the multiple call sites, the final HTML output isn't really the same and this forgoes all the messy conditional logic and awkward data massaging that the original developer included.
As far as buttons go, the easiest is to just use
<a href="#" class="button">Click Here</a>
and <a href="#" class="button button-primary">Click Here</a>
everywhere. Look at that, turns out CSS is a component framework already ;)<include src="myComponent.html>
https://hacks.mozilla.org/2015/06/the-state-of-web-component... (ctrl+f "HTML Imports")
"HTML Imports do lend themselves well to a simpler/more declarative workflow. [...] Imports don’t offer enough control to be taken seriously as a dependency management solution. [...] Mozilla had a working implementation behind a flag, but struggled through an incomplete specification."
which to me reads a bit like: "js frameworks won't use it, and the spec didn't get enough love because everybody's only thinking about frameworks rather than vanilla-js."
It was much more akin to JS imports. HTML files would be side-effectful, then you could use the elements they defined, like <x-foo>.
A web that was built on documents fragments because the JS and server-side developers think writing raw HTML and CSS is gross.
Email developers would like a word with them.
This isn't going away, and at some point, adding more abstractions is actually harmful.
As I have little else to do at this point - Tl;dr When you work for a public library, but are closed the public, nothing happens - I'm rewriting a small microsite I made for job hunting purposes.
Other than a Service Worker cache, it's markup and styles all the way down, stitched together with Make.
For my blog, I've stuck with Liquid, because Jekyll - which I actually like (ducks) - will be interesting to see if this gets revived and actually lands one day.
Started on GH Pages, but moved to Netlify which gives me a bit more fine grained control.
Pardon the dust;
First, I'm not a graphic designer and second this is actually an older deploy that I've "locked" so I can continue tinkering with the master branch behind the scenes. Will be a single page with just anchors to navigate when done.
Everything old is new again. Homepages, kids, ask your parents about them :)
<script type="module" src='https://unpkg.com/html-include-element'></script>
<html-include src="./my-local-file.html"></html-include><!--#include virtual="/cgi-bin/counter.pl" -->
Thus JS library references basically enable HTML includes.
i've been doing a little Vue and a little WPF/XAML lately. with Vue SFCs, i find myself constantly scrolling up and back down in long files. with WPF, i'm switching between the XAML markup in one editor tab and the code-behind in another. i find the WPF workflow is better for me, because i lose my place less often.
I prefer by far keeping the CSS (or SASS) separate from the rest. React's mix of JS and HTML-ish is very comfortable, but I can't say I love it more than "native JS + some kind of templating". However, I'm absolutely certain that I prefer the CSS left outside the rest. My reasons include:
- you (probably) don't have to recompile the whole JS app to get your style changes - it's much easier to see the relevant JS when you don't have to skip over CSS or lengthy class names - it's much easier to see how bits of CSS relate to one another when they're in the same file (which I'll admit can make _some_ parts of that job harder, some of the time) - when the browser's dealing with "proper" CSS, you can use the browser tools to test changes before updating the source files, skipping around the DOM, watching all the selected elements change (which doesn't always happen when you have CSS Modules style scoping going on) - code editor tooling is usually better - you don't have to remember whether you're writing your CSS in native CSS, snake-case, or JS style camelCase (I know some of the recent CSS-in-JS tech helps here, but why add a library to do something the browser already does?) - you don't need to add libraries to do something the browsers already do
I also find that in a well-architected application, very large components with lots of markup and styles are rare compared to compact and reusable components used to compose the more complex ones which ultimately means the more complex ones also need less styles and markup; really big components might need to exist in some circumstances, but usually it's a code smell. 1 file also means there is less uptake necessary when bootstrapping new components, you don't need to create 3 new files with matching filenames and import statements (yes, you could get an IDE or a script to do it but its just one less thing to think about with the 1 file approach).
Finally, IMO, in the case of components the distinction is more superficial than logical, breaking up a single unit into 3 highly coupled modules that cannot be imported and reused anywhere else feels unnecessary. You wouldn't break up a class with 3 large methods into 3 different modules and import those into the class module.
In the case where I do have to edit a really large files with lots of coupled logic, my editor allows me to view the same file in multiple views at different positions.
This is one of those things that usually boils down to arbitrary personal preference, often buttressed by people working backward from their desired result to construct objective-sounding "maintainability" rationales.
Pick a style and stick to it within the project's codebase. There's no wrong answer here, except "the only right answer is the way I personally prefer". I wish we had Prettier for file structure.
With single file components it’s much easier to track the dependencies and rebuild / scrap chunks of code without leaving cruft around accidentally.
Not until I experienced component-level CSS did I see it happen since now it's relatively trivial to see unused CSS.
__Vue actually allows you to split the sections into seperate files if you require it.__
Source: https://vuejs.org/v2/guide/single-file-components.html#What-...
Absolutely not for me, I much prefer Angular's style of separate files living in a dedicated folder. With Vue, I also find myself constantly scrolling up and down.
Small straight forward components -> sure.
Mid-sized components -> maybe.
Large component -> No, but probably you it's a good idea to see if they can be shrunk.
But I only have played around with this tech, so no real experience.
I don't see much of a benefit of having everything in a single file vs. many. We are going to split them up, as soon as they become unwieldy and people ending up spending too much time reading code not relevant for the task at hand.
What I do see a lot of benefit in, is having everything in one language (Typescript in our case) instead of three and all the IDE capabilities like autocomplete, linting, refactoring, etc. that come with it. But to be fair, I haven't done frontend in a while, so I'm not up to date what the state of the art integrations for html/css/js look like in comparison.
The approach only works for very small components, not for real world use cases.
That to me is the killer-feature.
I frequently find myself overwhelmed with the sheer number of files such a convention generates.
But the strengths of the single-file approach reveal themselves when you have a lot of small components - it enables you to just glance at a file and immediately know what's going on.
Also it puts a psychological barier against large, bloated components.
this is the most compelling argument for me... but i still find myself having to work with overly-large components written by others. and that's when i end up doing lots and lots of scrolling and losing my place.
i guess that's the difference. single-file components are superior iff you have good team rigor around component size.
So - this here is an updated, revised and improved version. Enjoy!
There’s also ‘jake press’, which goes through the JavaScript code, pulling out anything not actually referenced and binning it
(edit: and it occurred to me while in the shower, if anyone wanted to tell me where (roughly) you are located, and loading time for the 'released' site, it'd make me happy :)
https://github.com/wisercoder/uibuilder/blob/master/WebCompo...
All you need is this tiny 250-line lib: https://github.com/wisercoder/uibuilder
esp given how people learn online, a single-file example is much more palatable on e.g. stack overflow vs three files
way friendlier to learners
not that anyone is building large production apps with single files, but tooling quality matters and this is one way to measure it