DEV Community

Discussion on: Why the React community is missing the point about Web Components

Collapse
 
progrium profile image
Jeff Lindsay

It's a weird situation. As Benny mentions it's a false dichotomy. Sort of. I can write Web Components or React Components, and Web Components can be used in React apps/components, but I still need React or something to "orchestrate" the app, namely data flow and app logic. Using a Web Component base element like LitElement is basically choosing a framework that makes components built with them as reusable outside of that framework as React components. This makes me think we may even see more incompatibility between components as Web Components ecosystem develops.

So when I ask, Should I start building Web Components? I don't even have a good answer for myself. Clearly I'm interested in them, but pragmatically there isn't a big enough general draw to invest in them. Plus I'm doing stuff with WASM and a lot of this gets thrown out the window.

A different question is, Should I use Web Components that have been made? Yes, if they're good enough. There doesn't seem to be a ton there yet though.

Collapse
 
oenonono profile image
Junk • Edited

How does WASM have anything to do with whether or not it's useful to be able to extend HTML?

Do you still use the button element? h1? input? Web Components are just a way to let you create HTML elements for your own UI patterns.

As you quite accurately note, this is not the same thing as orchestrating an application. Nor is it the same thing as writing complex business logic services in WASM.

You still need accessible GUI components. The standardized set of them is still insufficient. That's where Web Components shine.

Collapse
 
progrium profile image
Jeff Lindsay • Edited

If I build a component framework in another language via WASM, I can't see a way to make those components play well in a Web Component ecosystem. That was the extent of the meaning behind my WASM statement.

Thread Thread
 
oenonono profile image
Junk

How do you make a UI accessible that doesn't ultimately render HTML semantics? If you can't build an accessible UI, why would you implement the UI with WASM?

Thread Thread
 
dan_abramov profile image
Dan Abramov

Note that iOS, Android, and other UI platforms are accessible without using HTML. While I'm not pushing for leaving the DOM, there is nothing in particular that ties accessibility to it — it's a matter of which low-level APIs are exposed and available.

Thread Thread
 
progrium profile image
Jeff Lindsay

because javascript tooling is That Bad? but in seriousness i don't really understand. 1) it would still render HTML, 2) most app UIs are not HTML.

Thread Thread
 
oenonono profile image
Junk

Weren't we talking about web UIs specifically? Are you using WASM to build native Android or iOS apps? What is going on in this conversation?

Thread Thread
 
progrium profile image
Jeff Lindsay

who cares any more

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

litelement components are reusable outside your app, if you write them to be. If you write them dependent on your app, they will be, but they don't have to be. The point is that you can write reusables and have them run anywhere, which you can't do with frameworks.

also, the notion that 'wcs need some framework to orchestrate them' is also applicable to react, since it's just a view layer as well.

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

The point is that you can write reusables and have them run anywhere, which you can't do with frameworks.

You can absolutely write a reusable React component that's used in non-React apps.

We even have an example of this in the documentation (using web components :-):

reactjs.org/docs/web-components.ht...

It's a few lines of code.

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

but you can't npm i some useful react component and use it in your non-react app (or if "can't" is the wrong word, "probably won't ever")

whereas I can npm i -S @polymer/paper-input @vaadin/vaadin-grid and use them in my Vue app, no problem.

Maybe I'm wrong about that, and I hope I am, but I think it's in line with the general sentiment out there - apps are either vue apps or they're react apps

Thread Thread
 
dan_abramov profile image
Dan Abramov • Edited

You can definitely do that if you want to.

For example: npmjs.com/package/web-react-compon...

or if "can't" is the wrong word, "probably won't ever"

That sounds more likely. But is it because it's so difficult? Or because using a declarative library lets component authors come up with more natural and expressive APIs instead of catering to the imperative lowest common denominator? I think it's the latter.

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

Cool package!

weekly downloads: 1

Thread Thread
 
dan_abramov profile image
Dan Abramov • Edited

So maybe this means the holy grail of "code reuse between libraries" is not actually so desirable by developers? See my last two sentences. :-)

People like writing expressive code. There's a lot of expressiveness you have to give up in the component API if you're writing it for all consumers — precisely because you can't assume a declarative abstraction on top.

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

react-google-maps has 34k downloads, and it's a leaf.

I feel like we're trading notes about technical implementation when this discussion was really started about what it means to have the bigger navy.

Thread Thread
 
dan_abramov profile image
Dan Abramov

Fair.

Thread Thread
 
drcmda profile image
Paul Henschel • Edited

Benny, you can npm install any react component and use it in any context you like, be it vue or vanilla:

codesandbox.io/s/p56vnm0kv0?module...

All you need is a dom node, the javascript boilerplate is about two lines, mount and unmount, which you can abstract if you like. If you know your way around your toolchain (webpack) you can shrink the overhead down to less than what a web components polyfill would cost you.

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

or I can

import('https://unpkg.com/@polymer/paper-input/paper-input.js?module').then(() => {
  const pinput = document.createElement('paper-input');
  document.body.appendChild(pinput);
});

without any toolchain whatsoever. I actually just opened a chrome tab to the new tab page and ran that in the console.

Thread Thread
 
oenonono profile image
Junk

Can !== Should

A whole JS library for one component? This is what we're advocating now? I despair. Literal tears.

Thread Thread
 
thesdev profile image
Samir Saeedi

@benny you have to use a toolchain or a bundler for a real production web app at the end of the day. Even Google (the big force behind WCs) suggests using them: youtu.be/mIWCLOftfRw?t=690

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

No you don't need a toolchain. That's the whole point. You shouldn't need one. You may add one as an optimization (which is what Google is suggesting there) and I do as well in some of my apps. But you shouldn't need one. You should be able to serve files that you edited yourself directly and they should just work in the browser. That's the web I grew up with and that's the web I want to show to my kids in a few years time.

Thread Thread
 
dan_abramov profile image
Dan Abramov • Edited

You can do that just fine with React. There are people who don't like JSX and they write vanilla JS, e.g. github.com/Jador/react-hyperscript....

And again, even adding JSX doesn't mean adding a whole a toolchain. JSX compiler is like a SASS compiler — one command to run a watcher which outputs files to another folder. No complex build systems.

It's irresponsible (to the users!) to ship code to production without a minifier. So you probably already have a build step if you care about your users. Why not put a JSX command before it?

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦
var h = require('react-hyperscript');
var React = require('react');

var AnotherComponent = require('./another-component');

module.exports = React.createClass({
  render: function render() {
    return (
      h('div.example', [
        h('h1#heading', 'This is hyperscript'),
        h('h2', 'creating React.js markup'),
        h(AnotherComponent, {foo: 'bar'}, [
          h('li', [
            h('a', {href: 'http://whatever.com'}, 'One list item')
          ]),
          h('li', 'Another list item')
        ])
      ])
    );
  }
});
Enter fullscreen mode Exit fullscreen mode
import { html, render } from 'https://unpkg.com/lit-html/lit-html.js?module';
import './another-component.js';
const tpl = html`
  <div class="example">
    <h1 id="heading">This is lit-html</h1>
    <h2>Creating HTML Markup</h2>
    <another-component foo="bar">
      <li>
        <a href="http://whatever.com">One List Item</a>
      </li>
      <li>Another List Item</li>
    </another-component>
  </div>
` 
render(tpl, container)
Enter fullscreen mode Exit fullscreen mode

🤷‍♂️

Thread Thread
 
dmitriid profile image
Dmitrii 'Mamut' Dimandt

The difference is obvious, isn't it? One is just JS functions. You can refactor them. Lint them. Runs code analysis tools on them. Split them out. Move to a different module.

The other one is a string blob.

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

You have fun with that... I'll be writing HTML

Thread Thread
 
dmitriid profile image
Dmitrii 'Mamut' Dimandt

It's not HTML though. It's a string blob inside Javascript code. You can wish it away, but the reality remains.

🤷‍♂️

Thread Thread
 
thesdev profile image
Samir Saeedi

If your problem is tooling then maybe this extension can help. Does it have to say .html on the file extension to be more than a "string blob"? HTML is text after all, it's literally in the name.

Thread Thread
 
dmitriid profile image
Dmitrii 'Mamut' Dimandt

That extension doesn't negate the fact that it remains a string blob inside Javascript. Having a string inside a programming language and calling it something else doesn't make it something else.

Thread Thread
 
thesdev profile image
Samir Saeedi

I wonder how do you feel about writing inside <script> and <style> tags in HTML. In which ways <script> alert("hi") </script> differs from template.innerHTML = "<div> hi </div>"? (Provided that there's tooling support and that the browser knows it has to parse the latter string as HTML not JavaScript.)

Thread Thread
 
dmitriid profile image
Dmitrii 'Mamut' Dimandt

I wonder if people actually know what tagged literals are in JS.

Hint:

html`string`
Enter fullscreen mode Exit fullscreen mode

is nothing more than a single function call with, you guessed it, a string

html('string', ...)
Enter fullscreen mode Exit fullscreen mode

No amount of word twisting and wishful thinking can change that. I really advise you to look at what lit-html does such as diligently parsing this string looking for tags and markers: github.com/Polymer/lit-html/blob/m...

And no. the browser does not know how to "parse this string as HTML". Because it's just a string, it's handled as a string, and is used a string, and nothing else.

Thread Thread
 
progrium profile image
Jeff Lindsay

Unsubscribe

Thread Thread
 
oenonono profile image
Junk • Edited

You all realize that JavaScript is just a string in a file without an engine to parse, compile, and execute it, right?

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

Well, it's a drop more complicated than that. Tagged template literals know about their static and dynamic parts. And lit-html uses template tags and weakmaps for fast parsing and efficient storage.

 
thepassle profile image
Pascal Schilp

Im fine with it being string blobs, string parsing is much faster than html parsing.