Conf42 JavaScript 2021 - Online

Build your next app with web components!

Video size:

Abstract

Build your next app with web components!

Web components have matured significantly over the last several year and are definitely ready for prime time. Writing a full blown web application with web components is now a wonderful experience.

What about my framework features?

  • CSS style isolation out of the box with Shadow DOM
  • Component based architecture
  • Supports ESM
  • Bundled (if you want)
  • Minified (if you want)
  • Documentation - Best on the web! (Thanks [MDN]!)
  • Supported by all major browsers (And IE11 with some polyfills)
  • Data binding - a little help from lit-html will go a long way!

MDN

Summary

  • Andrew Desmarais: Every line of front end code is tech debt when it's written in a framework. He would encourage you to rewrite it using web components. Web components have great style encapsulation built in. They also have some of the greatest documentation on the web.
  • Web components are a combination of a few different pieces of web technology. Custom elements allow you to define your own HTML elements. slots allow consumers to bring their own content into your components. templates are just for faster render times.
  • Shadow DOM provides beautiful style encapsulation. The next one is slots, and this allows components to take advantage of consumers providing their blown content. MDN really is some of the best documentation we have on the web. Is web component devtools really enterprise ready?
  • If you're writing native ESM, you can deliver your ESM directly to the DOm using a script tag. And then your markup is, well, it's just markup. All the major modern browsers support it. Is it really well supported?
  • Using basic string concatenation we can get through with 99% of what we really want to accomplish. If you really want some advanced rendering, we can go with a really thin and small library, something like lid HTML. And once again, if you want something that feels a little bit more fluent, then you can use lit HTML.
  • Vodin has a router that's a standalone router. It gives you a lot of the features that you're used to getting with a framework. One of the biggest features is lazy loading of JavaScript bundles. It's much simpler because of the SAS rollup plugin.
  • State management is the last big one. I really like to keep the kiss principle in mind, keep it super simple. If you're using GraphQL, you can always use Apollo for that. I hope that you'll choose web components as your way to build your next application.

Transcript

This transcript was autogenerated. To make changes, submit a PR.
You. Hello Comp 42 and welcome to my talk. Build your next app with web components. My name is Andrew Desmarais. You can find me on all the social medias at Teradocs. My website is Teradocs tech and my background is that I've been in the industry for about 17 years, started with building back ends for the most part, but over the course of the last decade have really strived to become a full stack engineer and worked with a lot of different web technologies, which is what has led me to the talk that you're hearing today about really trying to stick to the platform. So what's the problem? The problem really stems from the framework wars, the constant flame wars about frameworks. And it really is my opinion that every line of front end code is tech debt when it's written in a framework. The most pressing example I have of this is Angularjs. When everyone was really early in the framework world, Angularjs came on the scene and was the best thing that we had available. It really sped up our ability to create web applications quickly, and a lot of different companies latched onto it to build their enterprise software. This has since yielded a major problem. Angular JS was deprecated four years ago, five years ago at this point, and as of December 31 of 2021, it will no longer be supported at all. So that means that every application that was written in angular JS now must be rewritten into something else, and I would encourage you to rewrite it using web components. Outside of that specific example, we've all lost sleep to the framework wars. By choosing the right framework, you're always going to pick wrong because there is no good choice in my opinion. But I also think that frameworks equate to vendor lock in. Choosing a specific framework means that everything you do is going to be built in that framework, and you're not really going to have an opportunity to mix and match, very often without a lot of overhead. There's also upgrade fatigue. Like every time a framework upgrades, you really should be upgrading to the latest and greatest because there are security patches that to address vulnerabilities and there are new speed improvements in those frameworks that are being addressed. But that comes with a major downside of all of the dependencies that are bundled in with these frameworks that you're not in control of, you don't get to control if viewer react includes a new dependency that you're not in control of. And we've all seen some of the big problems that can happen with large dependency trees. With the breaking of the web in several cases, right thinking left pad, or in the large vulnerability cases that we've seen. So it's good to minimize our dependency tree as much as possible. So that's why I encourage you to use our newest ally that we have on the scene, web components. So I want to dive into web components a little bit to explain what they are. In case you're unfamiliar with them. It's important to understand that they web components based, obviously components in the name. They do come along with lifecycle methods though, so that's something that you're used to in all of the frameworks. Web components have them too. They have great style encapsulation built in just via the shadow Dom, and they have some of the greatest documentation on the web with MDN. MDN is supported and curated by Mozilla and provides probably the best curated documentation out there. So let's talk about web components. What are they? Web components are a combination of a few different pieces of web technology. I'm not going to cover all these super in depth, but let's go over them really quickly. So we have custom elements, which is basically the ability to define your own HTML elements. We have the shadow Dom, which is a way to encapsulate not only your CSS but also your HTML and isolate them from the rest of the Dom. Then we have slots, which is a way to allow your consumers to bring their own content into your components. Think content projection in angular or children in react or slots in view. And then there are templates, which is just for faster render times. It allows some HTML elements to be defined ahead of time and then cloned really quickly for use later. So getting in a little bit deeper on custom elements, they're pretty limited with the number of requirements that I have. The only requirements really are that the tag name has to be all lowercase and it must contain a hyphen. Outside of that you can kind of name it whatever you want. Believe it or not, something as obnoxious in my opinion, as t hyphen can actually be a valid custom element name. I don't know why that's allowed, but it is. So outside of that though, there's lifecycle methods. Lifecycle methods for these elements consist of connected callback, which is when an element is added to the DOM, disconnected callback elements removed from the DOM, and when the attribute changed callback, which is keeping track of when attributes are changing on that element. So really feels familiar if you're used to other frameworks with some of these lifecycle methods, and also nice minimal requirements. Thinking of style encapsulation, something that a lot of us have used different systems to encapsulate our CSS. The shadow DOM provides beautiful style encapsulation. Effectively, the shadow Dom creates a miniature dom that is isolated from what we call the light dom, which is the main documentary. By using the shadow dom, when you put a style sheet into it, that style sheet is actually isolated from the light dom and will not affect any other elements except for what is in the shadow Dom. The benefit of this is that we don't have to obfuscate our class names. We don't need build tooling that's going to do that for us. We can use regular old class names. Or if you're using really small amount of, very small amount of HTML, you could just reference things by their tag names. Because you're so tightly encapsulated, you don't have to worry about that bleed of CSS, bleeding outside of that component and affecting things you didn't intend. So super powerful to be able to have the shadow Dom encapsulating your styles. The next one is slots, and this allows components to really take advantage of consumers providing their blown content. So the example that you can see in front of you is a basic card component where I want the consumer to tell me the title and the image and the description of that image. And as long as the consumer provides those things in the slots, then the card will render exactly as you would expect it to. And you get all of this additional styling of all of the elements that are being brought in and all of this additional layout that the consumer didn't need to worry about because it's a component. The last thing is documentation. So MDN really is some of the best documentation we have on the web. It's extremely well curated and it's kept up to date in a much better fashion than a lot of other documentation out there. So all of the things I've talked about so far with web components are documented on MDM. I encourage you to go out and look at it because all of their documentation is absolutely fantastic. So one of the questions I get a lot when I talk about this to people is, is it really enterprise ready? And the answer is absolutely. Like, how enterprise ready is it? Well, YouTube, as a great example, is all web components. It's using web components for everything that it does. And how do I know this? Because of a beautiful piece of tooling called web component devtools, which allows us to inspect and interact with web components in a way that is a little bit harder if you're just using the native chrome devtools gives us access to attributes and properties and see the slots that are available and things like that. You can see it's still fairly new, it's young in its development lifecycle, but it is a pretty powerful set of tooling. It's also nice to see that things like YouTube aren't alone. We also have the Nintendo Web store, which is also based completely in web components. So if Nintendo is betting their financial gain on web components, you can bet that it's actually a well baked, enterprise ready piece of technology. So another question I get about is delivery. How are we delivering web components? What does that story look like? The nice thing is, if you're writing native ESM, you can actually just deliver your ESM directly to the DOm using a script tag. And then your markup is, well, it's just markup. Even with your custom elements, that markup is really readable and really maintainable because it is just HTML at the end of the day. So beautiful that web components provide such a simple delivery system. But what if I want minification and bundling and those types of things that my framework provides me? Well, we still have all of the bundling tools available to us. I've chosen to highlight webpack and roll up here if we want minification. These are the two examples that provide minification for you. So webpack gives you nine whopping lines of config that provide you with minification and a basic minified bundle. And then the same thing in roll up, a little bit bigger, but only 13 lines to give you that nice ESM bundle with minification using terser. But very, very small amount of work needed to be able to get some of that basic minification that we're used to. And then I wanted to rehighlight the fact that this is really just a script tag. Like how simple is it? It really is this simple. This is the entire HTML document to demonstrate that card example from earlier. So that one script tag comes in and that card HTML is just HTML. So it's super powerful to have something so simple to look at and read because it creates a high level of maintainability in the long run. The other question that I get is support. Is it really well supported? Yeah, it's extremely well supported. All the major modern browsers support it. And if you really need ie eleven support, there are polyfills out there for that too. So it is extremely well supported out there in the industry. And you know how I was talking about upgrade fatigue earlier. The nice piece is the browsers maintain the upgrade for you if something needs to be patched. From a security vulnerability perspective, the platform is going to patch it. If there is a new piece of functionality that needs to be released, the platform is going to release it. So it makes life really really easy to maintain. So let's talk about a lot of the common things that frameworks provide that we're going to need if we're going to build an application with web components, things like dynamic templates and data binding and routing, and bringing along our favorite CSS library that we want, and state management. Because all of these are questions that we need to answer if we're going to be convincing the people around us that we can do this thing with web components. So dynamic templates, it's just JavaScript at the end of the day. So using basic string concatenation we can get through with 99% of what we really want to accomplish. And that means that string template literals have kind of become the way to go. Using backticks allows us to define string template literals in a way that we can drop in the variables that we need to at the time that we need to. But if you really want some advanced rendering, we can go with a really thin and small library, something like lid HTML. If six k is too big for you, there's also things out there like micro HTML or UHTML that are even smaller at two k that provide most of the things that lit HTML also provides. But if you bring in lit, then you get dynamic template rendering, you get data binding, you get event binding, attribute binding, property binding, et cetera. And for a very very small bundle, data binding. Well the nice thing is that web components are just objects, just like everything else in JavaScript. So if you can grab a handle to it using a query selector, then you can just pass in complex data objects by passing them to a property on that tag. So documenting that is definitely a big deal, but it's also not that big, not that hard a thing to do as you're developing your web components. And once again, if you really want something that feels a little bit more fluent and a little bit more native, then you can use lit HTML to do that. Property binding in line routing is the next biggest one. People are so used to routing having to be something that is very very framework specific. But luckily there's a set of framework utilities out there, a set of UI utilities out there, sorry, called Vodin. And Vodin has a router that's a standalone router, you don't have to bring it along any of their other UI components. And that router gives you a lot of the features that you're used to getting with a framework. Things like child routes and fallback routes, and being able to grab route parameters and use those in your templates also handles redirects so that if you're upgrading a path away from one path to a new path, you can handle that. And one of the biggest features that frameworks tend to provide us is the lazy loading of JavaScript bundles. The Vodin router handles the fact that you don't need to load all of your JavaScript up from if you have a bundle of web components that aren't used on the first page and are only used on a second page of a wizard system, for example, then don't load that up from bundle that separately, load it separately, and Vaden's router will allow you to load that lazily as that navigation is happening. So bringing in SAS or less I'm choosing SAS in this example. Bringing in know going with a bundler is pretty much the only way that you're going to be able to do that. You need some build step to accomplish it, and with the shadow dom in play you're going to have to be able to import those things. So on the left is webpack. Not the smallest amount of config in the world, I will admit, but at the same time it's also not that complex. It uses both the SAS loader and the raw loader to be able to bring that in. And this allows us to import that style sheet like text so that when I'm importing it from within my component, I can actually just take the text from that SAS file and put it inside of a style tag and it will render appropriately to get that same functionality out of roll up. It's much simpler because of the SAS rollup plugin. Simply setting output to false on the SAS rollup plugin means that it will output text to the import and that allows us to use it exactly like we would want to. State management is the last big one. So how do we handle state management? I really like to keep the kiss principle in mind, keep it super simple. Keeping it super simple means don't overcomplicate things because they feel like they are complicated. State management can be kept very simple. As an example, one of the ways that I like to keep state management simple for my applications is I use singletons. If I have a user that could appear somewhere in the application and it could appear in many different places, then having a singleton class, which is effectively a class that only is ever instantiated once, but can be fetched many times. Having that Singleton class manage the state for that user means that I can reference it anywhere in my application, but it's only held in one place in memory. I don't have to worry about fetching it multiple times or how to do caching that can be handled by the Singleton service that I've created. If you are growing really, really large and you have a lot of state to manage, you can always go redux. Redux is just Javascript at the end of the day, but I found that to be overkill in the vast majority of cases. And the last one is if you're using GraphQL, you can always use Apollo for that. Apollo has a lot of good caching and state management built into it that will help you out if you're using graphQl. So thank you very much for taking the time to hear me out on this web components thing. I hope that I've opened your eyes a little bit to what's available to you out there, and I really hope that if you're given an opportunity to in the future that you'll choose web components as your way to build your next application. Thank you.
...

Andrew Desmarais

Principal Software Engineer @ Meltwater

Andrew Desmarais's LinkedIn account Andrew Desmarais's twitter account



Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways