1. Libraries like lit-html have syntax highlighting and tooling to do type checking.
For the developer: https://marketplace.visualstudio.com/items?itemName=runem.li...
For node: https://www.npmjs.com/package/lit-analyzer
For other Web Component libraries: https://www.npmjs.com/package/web-component-analyzer
2. Totally agree on slots. They suck and were hamstringed by Safari in spec talks. Libraries like LitElement have the concept of reflecting a property to an attribute and it's really easy to do so. Also, Chrome had a property explorer in dev tools that just got deprecated which also sucks.
3. Attributes are strings, yes, but you can also set properties on a component. Easy to have a setter and getter for a property (can easily be turned into a TS decorator) that just calls a render method on change, but again, the cost for attributeChangedCallback to serialize a primitive is very low. Passing objects should just be sent as a prop, but also, passing objects to child web components we've found is a bad habit. Often the props of an object should be spread (easy to make a directive of this in lit-html) over the props of the child and arrays typically easier to turn their contents into DOM nodes.
Also none of this takes into consideration of a web component using a state library like redux.
Things might have changed, but it’s easier to recreate web component features in JS than it is to convince people to use a two-way object-oriented API that’s mostly stringly-typed unless using JS. If the problem we’re solving is we want a faster web, bake in and follow top JS libraries such that how they render is part of the spec. I’d be very interested to see what a React scheduler would look like if implemented in C++ on top of the browser’s scheduler.
I really like parts of web components, but... I’d also like to see a Chrome experiment where JSX and TS is baked into the browser to natively solve the “stringly-typed” problem the Web Components spec has. Maybe that’s going too far, or maybe we’ll end up shipping these features as “modules” that can be toggled on if compatible.
I think it would help the web move to where developers are to include native understanding and support for semi-“proprietary” solutions given widespread adoption. For example, ES Modules are great, yes, until you have to start building your own vendor modules because somebody shipped a Webpack module as dist, for example.
Just as Babel lets us try new syntax earlier, so too could third-party libraries popularize new browser-native APIs as loadable modules, maybe? (My assumption being that integrating with existing C++ is cheaper than writing scheduling and DOM update logic in JS, but the JS is cheaper to ship, so some kind of browser-module-loading-with-JS-fallback is the only way we can have performance wins for existing approaches while still shipping new versions of features given how fast JS syntax and preferences change?)
In practice, most libraries built around web components only use attributes when serializing / deserializing HTML strings. When performing updates to existing DOM, it is very common for a library to use a corresponding property instead. This is very fast, supports all types of values, and many libraries enable users to think in terms of attributes while the library updates properties under the hood (conceptually similar to the React mental model).
By using attrs, they show up in dom explorer, so it’s neat, don’t need another devtool. attributeChangedCallback will only be called when the attribute changes.
For props, it’s a bit more work since HTMLElement itself has a ton of built in props, using a setter means anytime something sets, it will he called, even if the property value isn’t different. the worst thing is when you end up overriding an internal prop and weird things happen.
This gives you compile-time checks, and attributes can be objects.
Properties can be complex objects, do not trigger attributeChangedCallback, and don't need to be serialized.
What are you using to build your web components if you think they can only take strings?
Yes, it requires a plugin, but JSX required the parser, compiler, and type-checker to explicitly add support for it. They both require an extension to core TypeScript.
1) Their templating library has a learning curve. It's not quite like svelte, nor like JSX. If you have templates as strings that aren't typechecked, it makes it really hard to work on large code bases where the components are built by someone else and you're the consumer. I remember breaking powerbi.com due to missing > in an angular template that ended up in prod that only triggered for non english customers. It was a hard lesson that day never to touch untyped string based templates ever again. It's so easy to miss something. You want strict compile time checks, not run time.
2) Being dependent on slots. It's not easy to watch for changes in attributes to a slotted child. Yes you can add mutation observers but they aren't cheap either. All sorts of bugs poped up because some code does querySelector(x).setAttribute on a slotted child but the parent doesn't rerender and the UI doesn't look right. We ended up going to json strings inside attributes so components take their inputs via attrs rather than reading slotted children. The other avenue is props (like ionic), but props don't show up in dom explorer, so you have to make the tradeoff.
3) the 3rd big gotcha of web components. Attributes are strings. You have to serialize and deserialize from strings. Sure you can listen to when they change via attributeChangedCallback and get immutability for free because of serialization, but that comes at a perf cost. for deeply nested objects, you have to serialize and deserialize from json.
All in all, I love that Microsoft is doing web components. Webcomponents are part of native dom api with simple lifecycle api. They're neat.