📜 ⬆️ ⬇️

Web Components is the only bright future for the web. Humble yourself


Yesterday came out [a very decent article about Web Components , and I realized that I could not help but share the experience that I had accumulated over the past eight months. I will not talk about how to work with Web Components, I will tell you why. Therefore, those who do not know about this technology stack should read the article at the link above.
The fact is that in June the first stable version of my CornerJS library was released . Starting as a standalone implementation of directives from AngularJS, it gradually became simpler — both in use and in implementation — the counterpart (inaccurate, yes, I know) of Custom Elements from the Component Web specification.

I went through a large number of bottlenecks, and now this library is used in several large and not very real projects.

This is a wonderful, in my opinion, implementation library — I really considered it the main tool in development, and in the last project (video portal) it turned out to be more important than jQuery: I could refuse from it, but not from it.
')
But I, as a person who introduced it to our team, and refuse it - we are switching to Mozilla X-tags for IE9 + sites and Polymer for IE10 + sites. Fortunately, in my memory we only had one or two IE8 + projects.

And in this post I will explain why web components are not just the future of the web. And the only future of the web.



How it all began



Prerequisites for such an architecture appeared four years ago in Google and Yandex, while maintaining the national flavor .

So, AngularJS appeared in Google - a framework in which most of the logic was based on directives. Why is this so important? Because the directives were modules that were attached to html-tags and were executed in the isolated environment of this node. The coloring here lay precisely in the fact that Google remained faithful to the Java-like approach, and built everything around non-native setters and getters. On the one hand, this is correct, it was the only way to make an “almost honest” callback for changing Submissions, on the other - it brought some inconvenience in using the library. However, what we are talking about, we are already accustomed to everything, one can say. But as a result, the main thing appeared: autonomous visual and not so elements that can be easily transferred from project to project. By the way, they say - I, unfortunately, for the last few months have not been tracking the progress of AngularJS - that they have already moved to almost native Object.observe.

And in Yandex, BEM appeared, the National Russian idea with JSON and layout designers . Somewhere in the comments I expressed my position towards him: “BEM is an attempt to fly into a bright future, waving crutches. On the one hand, it did work out; on the other, it is impossible to watch without laughter or tears. ” However, the rozzyga week on the BEM topic has already passed, so do not discuss this topic in the comments, please. I just wanted to say that the approach in itself is really worthy of admiration: to understand and make the mechanics that provide encapsulation of both styles and scripts (yes, and in an angulyar only scripts are encapsulated) - this is brilliant, and how it is done - This is the second thing, and those who really need it, have long accepted and used.

Eventually...


... we have what we have: large teams have come to the realization that not only libraries should be encapsulated and connected (hello, requireJS and my personal browserify favorite), but first and foremost are visual components on each of the pages of the site.
Why? Yes, because they do not belong to the main flow of the program. If you have a web application, how should it relate to rendering a chart on the main page? No, the ideal option for you is to declare it in the template, in the necessary HTML tag input data, and then let it work itself. You really don’t want to think about when to start rendering the data, and if you suddenly want to dynamically update this data, all the more you don’t, it’s much more convenient for you to simply add some

<value at=100 is=500> 

You already use this approach, see:
 <video width="320" height="240" poster="poster.jpg" controls="controls" preload="none"> <source type="video/mp4" src="myvideo.mp4" /> <source type="video/webm" src="myvideo.webm" /> <source type="video/ogg" src="myvideo.ogv" /> </video> 


And the core of your web application should do really important things: rendering pages with content, dynamically updating them, working with the network, background processes, or AI and speech recognition (and why not?). Yes, and even almost all of this in general can be made separate web components.

Modular web


Over time, when you begin to actively use libraries for web components (or BEM, with which supporters of this approach agree, although I feel that they have already hated me) suddenly comes the realization that a single application, as such, is almost never needed . Each web page is an autonomous entity, isolated from the outside world, it is good in itself, and an application is an entity that remains between pages and is almost never present. The fact is that transitions between pages can be partial, and some User Elements can easily and naturally remain on it, for example, a player or a chat.

The result is a very simple thing: 90-95% of websites can only be built from autonomous components, which are modules that combine visual presentation, logic, as well as external methods and properties. And, of course, they may contain other modules.

Those implementations of this approach that are now, in fact, terrible in terms of the visual component. If, in terms of logic, you can safely create a combined AMD / npm / non-modular component with a fairly good set of tools, then with a visual presentation it is more complicated: you have to have a template engine inside the module, use inline-styles or fit into document.styleSheets, and all neither can you be sure that the web developer will not touch the module with his styles. Suddenly he has some footer a and he inserts your block of likes there?

Hi, components


Based on the experience of the google, mozilla and many other teams, they jointly came to realize that you need to create the ability to implement isolated logic-visual modules. Experience told them that it is really very important:

Css encapsulation

This is the ability to completely isolate css-styles so that document styles do not affect the display of the module. Why this is important is understandable.

Custom methods and properties

This is the ability to create external interfaces, both methods and values. Fortunately, in js it is quite simple to do, and the getters and setters have appeared relatively long ago. Thanks Object.defineProperty. This is important because custom elements must have new interfaces. How would you implement the video tag without
 HTMLVideoElement.prototype.play() 
?

A bunch of callbacks for every sneeze

constructors, destructors, and callbacks for changing attributes. Unobvious moment: there are two callbacks of the "designer". The first one is responsible for creating the element (document.createElement ('x-tag')), and the second is responsible for adding it to the DOM tree. In case you just added an element to the layout, both will shoot. Why do you need it? Because some actions (for example, triggering events) should be performed on adding an element to the DOM tree. Moreover, they must be performed on each addition of an element to the DOM tree, including if you transfer an element by passing it through appendChild to another parent.

Templates without performing content

Their importance is not very obvious at first glance, seemingly “yes, everything is cool, now the pictures will not be loaded,” but there is a break from the context of User Elements: people forget that they, too, are triggered by adding to the DOM, and if earlier in some MVVM framework, you could easily insert something as a template and forget - nothing will happen to it, but now you need to take into account that the elements declared in the template tend to be initiated, and some
 <x-video-with-subtitle source="{{video.source}}"> 

will be launched with {{video.source}} as a source, which does not suit anyone at all.

Layout encapsulation

This is also not a completely obvious point. The fact is that in the same way styles, there should be no influence on the layout of the User Element: it must be completely autonomous, you can “get through” to it only with special street magic - just to make standard libraries not able to work with it .
However, there are often not enough attributes to configure an element, and for some diagram, the most appropriate solution would be to create something like
 <x-diagram type="histogram"> <value at=100 is=500> <value at=200 is=300> <value at=300 is=200> <value at=300 is=700> </x-diagram> 


Therefore, it was necessary to do two things: encapsulation of the real typesetting and support for the simplest (at the tag level) its template. Both things have worked out pretty well: Shadow DOM is both a way of encapsulating styles and structural layout at the same time, as well as a simple, but rather convenient template in some places.

That article did not explain, but I will try to clarify about templating: in fact, the Shadow DOM templating engine is not limited to applying the tag.
 <content> 
head-on. It has a select attribute, and with it it looks like this:
 <content select=".first"> 
This tag "removes" from the host DOM component all the elements that fall under the tag. Accordingly, the second time this search will not find anything. So the spelling
 <content></content><content></content> 
in reality, it will simply transfer the contents of the host DOM to the composed DOM, and the second tag will not be able to transfer anything, because there are no elements anymore.
If someone still doesn’t understand anything, try this great demo that shows how the Shadow DOM still works.

In many publications, he was subjected to harsh criticism because he did not have any supernormal abilities, such as iterators or filters, or even simply the ability to insert an element twice. Unfortunately, nobody really spent time on opponents, but it would be necessary. The fact is that shadow DOM is not a template engine in the usual sense of the word: it does not create elements from templates. He is engaged in direct forwarding of elements. If you put an element in the host DOM, and change its attributes, they will be available and modified in the shadow DOM. If you put one User Element into another User Element, the constructor for the nested element will be called only once, and it will not have a sudden realization that it has been moved somewhere, and the constructor must be restarted. It was the only possible reasonable option for implementation.

Custom Element Announcement


The script tag was not suitable for declaring such elements: in fact, most of the tag was a layout. In some - I would even say, many - cases of scripting can be avoided in principle. Therefore, the most sensible solution was to extend the specification of HTML itself with another element with a slightly “special” syntax.
But here there is a need for another solution: how to cache these elements? We cannot connect them via script , because this is not a script tag, which means that we need to create a specification for another way of connecting elements. This is how HTML Imports came about.
I will not tell you more about them, of course, it’s interesting, but the article is already quite large.

The very same approach with the creation of new tags appeared for a number of reasons, but one of the main ones I would call the impossibility of linking two designers to the same tag. At one time, I spent half a day trying to debug a licensing agreement directive. The tag looked something like this:
 <div class="directive-agreement directive-scrollbox">    ,     ,        </div> 


For a long time I could not understand why I didn’t have a scrollbox. And debugger showed that it is created ... and then disappears.
It turned out that the directive-scrollbox is the first to work. A directive-agreement is the second, and also transforms innerHTML.

Eventually


The Web Components specification is very well thought out, and is built from separate modules that, together, are aimed at one simple task: to provide a really convenient way to create new HTML tags that encapsulate the visual part and logic. This can speed up the creation of websites at times due to the fact that it becomes easier to connect them, and in many cases it can be done by the maker-up without the help of front-end developers. Front-end developers are also making life easier, their work is actually divided into two parts: the creation of stand-alone modules with logic and a large, convenient set of external interfaces, and the creation of a web application core. At the same time, the second activity is more related to senior developers who are already tired of creating “cool animated effects”, and the first is much easier to parallelize, and much easier to test: testing moves from BDD, which for a long time was the main for the web, to unit testing, which each component is tested individually.

The HTML Imports mechanics are especially important for the development of the web, since they almost guarantee the creation of an online repository / CDN with a large number of web component libraries, and as we know, centralized repositories have a positive effect on the quality of the code created by the community: everyone is trying to improve their content. reputation, issuing quality code, the community itself is actively developing, and the necessary modules and libraries become easier to find and connect. Centralized CDN is able to provide faster loading of web pages (this is the scourge of our days, the page size increases faster than the speed of the Internet increases at the end user).

As a result, almost certainly in literally 2-3 years most of what is now represented by libraries will be implemented as User Elements, because it is trite easier to use and maintain. Sliders, responsive images, WYSIWYG and Markdown editors, video with karaoke support, a generator of purring cats on the canvas, in general, almost everything on the web can be wrapped in a Custom Element.

The funny thing is that the element does not have to be visual: why not do something like that?
 var $ = document.createElement('x-library-jQuery') 


Web Components gives you a convenient interface for creating custom libraries, which is at least standardized, and it is really convenient.

Start using them today.
Try it, you will like it.

If you are developing for IE9 + - you can use Mozilla X-tags (now they have a UPS, use the repository )

If for IE10 +, connect Polymer and use honest User Elements or use a lighter syntax and extension of the Components Web in polymer.js. Sincere thanks to Google for investing heavily in Polymer and creating ie10 + (and some even IE9 +) polyfills for all components of Web Components.

I hope I was able to tell you why everything was done this way: I went through this in my own experience, with each version of the library getting closer to X-tags, because such a syntax is the only possible implementation of a “reactive” approach to working with visual components, and getting closer to understanding the causes of some strange and difficult at first glance things.

Afterword


Recently, there has been more and more talk that the web is becoming more fragmented. If you need to connect a browserify module and an AMD module, this will cause ... some problems. Some libraries are adapted for TypeScript, some for CoffeeScript (well, okay, I know you can work with them, but many CoffeeScript can easily be intimidated if you need to fix small bugs in some small library or add your own methods). Dart is generally a separate language that far from perfectly interacts with ordinary JS. Web Components can remove this fragmentation: all components will be compatible with each other, because it will be just HTML. Albeit with new elements. Google can easily create components on their Dart, you can use icedCoffee, Facebook will continue to scare everyone with its JSX, and in Odessa they will develop modules in liveScript and beyond.
You can still use these libraries, because all of them will have the same way to interact.
Please start using them today, and you will make the web better: any developer will be able to use your library, regardless of whether he writes in pure JS, or on any of the preprocessors, or does not write at all - think about the slider, for example, It does not need to be initialized from JS, it is enough that it will be configured through attributes and internal content. In the end, two-thirds of the libraries for jQuery are probably just something like $ (). Mediaelement (config) and that's it.

PS I propose to declare the week of Web Components open

Source: https://habr.com/ru/post/210130/


All Articles