What is polymer CLI

Stefan Neumann 6

A change is underway in web applications. Anyone looking at the source text of a website in the future could be surprised by a single my-app element in the body of the page. No trace of the usual hodgepodge of hundreds of divs and other elements.

Using components in software development is not a new idea. On the occasion of the 25th anniversary of Visual Basic, we would like to remind you of the ActiveX controls, which have made life easier for countless developers in a similar form under .NET. From the jQuery plug-in to trendy frameworks like Angular and React - all of them build on components, often referred to as widgets, in their own way. So why the growing interest in web components?

The answer lies in the penultimate sentence with the words "in their own way". All "controls" of a platform for desktop development (such as .NET) have in common that they are integrated in a certain way and interact with the platform in a certain way. This makes their use consistent and therefore easy despite all the specific differences. Also, no control element will ever influence another unless it pulls the whole program into the abyss.

With the web as a platform, things are different. With larger projects you are spoiled for choice. Which framework, which library best covers the requirements? It is not uncommon to find out that a combination of several offers would be ideal, but this not only increases the loading times disproportionately, since each framework has its own substructure. The chances of intolerance are not low either, especially with CSS. JavaScript also allows a lot of freedom, so that the use of every new library and every new plug-in begins with researching how their integration was implemented. In some cases, existing HTML is used, other products generate it completely themselves.

The consistent use of web components could put an end to this, because this is not only about programming your own HTML elements, but also about a paradigm shift that uses the DOM as a framework. Quite a few are surprised that web components are also created for purposes that are not visible on the website. The web application is ultimately created by the nested combination of the components. If you take that to the extreme, in the end there is only one web component left that makes up the entire application. In relation to the design pattern, the "mediator pattern" is used here. A web component knows little about the page it is sitting on; it is integrated and guided by the component sitting above it. Communication takes place via the values ​​of attributes (the component reacts to their change), ultimately via DOM events.

Fortunately, standards

Web components also have the advantage that they are based on W3C standards, more precisely the specifications for "Custom Elements", "HTML Import" and "Shadow DOM". Important browser manufacturers have committed to these standards, have already implemented them or are in the process of doing so. The past has shown that it is difficult for individual applications to compete against standards in the long run.

"Custom Elements" enable the actual creation of the component (together with the HTML5 templates), "HTML Import" enables these to be loaded onto the page, and the "Shadow DOM" finally ensures that the components do not interfere with each other come the way.

Areas of the DOM that are not generally accessible have existed for a long time. The controls of a <video>-Elements are usually just HTML elements themselves, but they do not appear in the DOM. This area is located under the actual DOM, namely "in its shadow". Browser developers only have properties and methods for the <video>-Tag are provided that enable interaction via JavaScript. The Shadow DOM specification allows developers to do something similar. A web component behaves as if it were inside one <iframe>However, developers can define exactly where it is "permeable", including when it comes to styling. To distinguish it from the shadow DOM, the actual DOM is also referred to as the "light DOM".

Web components must be registered in the browser. With each new component, new, repetitive code is created, which similarly also exists with desktop controls. Thanks to an IDE like Visual Studio, developers rarely have to deal with it. With the second or third component at the latest, web developers will also think about how they can simplify this process, or they will fall back on existing libraries such as Google's polymer.

polymer

Polymer - elements according to the periodic table

Despite Angular, Google has started a project with Polymer that aims to promote the use of web components. It combines polyfills and syntactic sugar into a library that enables the use of web components in every reasonably up-to-date browser.

The project includes ready-to-use elements that have been subdivided into those of the periodic table following the "chemical" naming. Under "Md" (Mendelevium) there are many components with which the material design propagated by Google can be implemented. There were probably many objections to this type of naming, so that Google has now deviated from it with the "App Elements". Here you will find invisible components that take on tasks that developers would otherwise tackle with application frameworks.

Angular vs. Polymer

Anyone who asks the Polymer team about their relationship with Angular will, as expected, get answers that emphasize the raison d'être of both projects. It would actually be possible to use both. With the rewrite of Angular 2, one was already looking towards web components. But if you only see a UI library in Polymer that ignores many aspects of Angular, you are falling short. In the "App Elements" of the "Polymer Element Catalog", overlaps with Angular can be recognized.

Initially, many polymers crammed into the "plug and play" drawer. After the import, the element is inserted somewhere on the page - done. This is possible, but in more complex applications the component is used more as part of its own, which can even continue over two or three levels before the element appears in the Light DOM.

Since the IO 2016 it has become clearer how Google envisions the future of Internet development with polymer. The "Carbon Elements" have been renamed, the "Polymer App Toolbox" introduced, and there is a shop for outerwear that demonstrates the new possibilities. This application is examined more closely here, whereby it should quickly become clear that Google requires web developers to rethink their approach to a certain extent.

Many web frameworks come with a command line program (CLI) that relieves you of annoying tasks and thus shortens the time to the first finished app - this is also the case with Polymer, whose CLI is based on Node.js. It supports the entire development process from the creation of ready-made program frameworks to the combination of build tools that prepare the project for deployment. Interesting for larger companies: You can integrate everything directly into your own processes without the CLI. The toolbox thus combines a utility program with the renamed "App Elements" to impress developers on how quickly they can get an app online. Of course, Google's own Firebase cloud environment is supported here, which developers can also use if the app does not require a database at all.

Bundled or not bundled?

With HTTP / 1.1, the browser alone decides what the server should load. Loading each resource has a certain overhead, since a new connection is established each time. Therefore it makes sense to bundle the files before transferring them. HTTP / 2 is supposed to shorten the loading times of pages. It is no longer the browser alone that decides what is loaded. The server uses its information advantage and gives an already opened stream everything the browser needs (even before it has analyzed the HTML). Bundling files would be counterproductive here, as the server would have to take out the resources for the server push. Therefore, Polymer CLI produces two variants of the project, "bundled" and "unbundled" - depending on whether the web server supports HTTP / 2 or not.

Back button support

The more a website goes in the direction of a web app, the more developers want to avoid that the page is reloaded with every action by the user. Not least because the status of the app is lost in the process. Developers therefore use single page apps that are only loaded once into the browser at the beginning of use and otherwise only exchange information with the server via XHR (AJAX), WebSockets or the like.

Now all you have to do is click the back button in the browser and the app will be closed. Contents made available by the app can no longer be indexed by search engines; they do not have their own URL. That would be fatal for a shop. A potential customer could not even save the Internet address for a product in their browser.

"Client-side routing" is used as a solution. The term originally only used by networkers means the process of mapping a URL to content in web apps. The Internet address is analyzed in order to decide which parts of the program display which data. This usually takes place on the server, but this is not a viable option for single page apps. However, you have to use tricks so that search engines and users can use links in the app without reloading the page. For a long time, the hash was used here, which is intended to jump to content on the same page. The URL only changes after the "#", the browser sees no reason to reload the page.

The method is likely to increase here in the future pushState of HistoryObject are used. All common browsers support the manipulation of the browser history (Internet Explorer from version 10). Only Opera Mini is still mobile. History allows you to click into the browser's back button. The app is informed when visitors want to return and can use pushState () affect the display of the address. The hash no longer has to appear here. At the same time, the click on a link is intercepted and blocked via JavaScript so that the browser does not reload the page. It goes without saying that Google uses the more modern variant for its case study.

Now developers have the problem that an address stored in the browser (or on Google) cannot actually be called up. In the case of a shop, it addresses a product, but the web server assumes that there is a sendable file behind the address. For this scenario, you need a certain amount of control over the web server in order to typically redirect all requests that "run nowhere" to the file that is loading the shop index.html. With the Apache web server, this is done by a rewrite instruction.

Web as a platform

Don't be afraid to use the platform

At Polymer, the app elements take care of it <app-route> and <app-location> about the client-side routing. They are a nice example of how web components work together, which actually do simple tasks, but do the job in conjunction with other elements.

The following is also an example of polymer data binding, which facilitates communication between the elements. The page source code was essentially generated by Polymer CLI:

<!doctype html>
<html>
<head>
<title>demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="manifest" href="/manifest.json">

<link rel="import" href="src/demo-app/demo-app.html">
</head>
<body>
<demo-app></demo-app>
</body>
</html>

The first thing you notice is the inclusion of the manifest file. It follows the W3C specification for web app manifest files and contains application metadata as required for Google's progressive web apps ambitions. More on this in a future article.

Next will be webcomponents-lite.js loaded, it contains the gaps in the browser's polyfills. The bower_components folder is from using the Bower package manager. The Node.js module simplifies the download of the JavaScript libraries. First and foremost, it resolves dependencies, which can otherwise be problematic, especially with new versions.

Finally will demo-app.html imported and inserted in the body of the page:

<link rel="import" href="../../bower_components/polymer/polymer.html">


<dom-module id="demo-app">
<template>
<app-location route="{{route}}"></app-location>
<demo-location route="[[route]]"></demo-location>
</template>

<script>
Polymer({
is: 'demo-app',
});
</script>
</dom-module>

Here, developers first download everything they need for the app: Polymer itself, the app route housed app locationElement and its own element demo location. In <template> is the HTML that <demo-app> incorporates. When polymer analyzes it, the brackets are worth the routeAttribute discovered. They indicate that data binding is desired: in the case of the curly brackets in both directions, in the case of the square brackets only in one. in the <script>Element is what polymer requires minimally. Here the element is only named. How easy the data binding
works, makes that clear demo location-Element:

<link rel="import" href="../../bower_components/polymer/polymer.html">

<dom-module id="demo-location">
<template>
<p><span>location:</span> <span>{{route.path}}</span></p>
</template>

<script>
Polymer({
is: 'demo-location',
properties: {
route: {
type: Object
}
}
});
</script>
</dom-module>

The properties of polymers are to be made known to which it should pay attention to the element. It does this by creating the object properties. Minimum is a type declaration. Since the route-Property of location-Component of type Object is to be stated here. The object has a "path" property that the template uses.

Assuming that the app goes through http: //localhost/polymer-demo/index.html would be called in the browser, the page now shows "location: /polymer-demo/index.html at. The ones from locationElement created "path" property was added to the page without developers having to write code for it. With polymer, this happens automatically. But this only works as long as one does not leave the context of a component made with polymer. Would the items <app-location> and <demo-location> Sitting on the side directly in the Light DOM would not create a bond.

Capable of lazy loading

Polymer allows elements to be loaded only when they are actually needed (lazy loading). To do this, it is necessary to intervene in the routing process. You pause the loading of new content to ensure that the elements you need are already there. If not, it will not continue until you agree importHref have been loaded. The next step will be <demo-location> by <app-route> replaced as intended by the polymer creators.

route = "{{route}}"
pattern = "/: page"
data = "{{path}}"
tail = "{{tail}}">
</app-route>

The element can be viewed as a function, with the attributes route and pattern display the input, path and tail the edition. The element becomes active when it is data-bound to
<app-location> the value of route changes, i.e. if something changes in the address box of the browser. The pattern can be used to specify which parts of the path should be named and how.

The procedure is somewhat reminiscent of that extract-Function of PHP that transfers the values ​​of an associative array to individual variables. The above path leads to an object with the property "page", which has the value "polymer-demo", and this object is accessed via the data-Attribute made known to other elements. What is not covered by the pattern ends up in the tailAttribute, in this case "index.html". You can sense how things will continue: Another element connects with app route and uses its values ​​to present content.

In the case of the shop, this is iron-pages. Google has gathered components of a fundamental nature under "Iron" (Fe). It does little more than make sure that only one of the child elements is visible at a time. The developers speak of views in this context. The shop knows five of them, and each view is implemented via its own component, <shop-home> for the start page, <shop-cart> for the shopping cart et cetera.

selected-attribute = "visible">
<div name="one">1</div>
<div name="two">2</div>
<div name="three">3</div>
</iron-pages>

The value of the attribute selected decide which one <div>/i] sichtbar ist. Standardmäßig lässt sich hier der Index angeben. Der Autor folgt aber dem Shop und gibt den Elementen einen Namen. [i]<iron-pages> now needs to know what to use. This is done via its attribute attr-for-selected. Stands in selected-Attribute "two", the number 2 would be displayed in the example. The shop also uses selected-attribute. Developers use this to set an attribute for the currently visible element. In the Chrome Inspector, developers can observe that the visibleAttribute is present. The component can now react to whether it can be seen or not via so-called observers. The article leaves out details, it should only be made clear how the DOM is used here.

The higher-level component takes over in the actual shop <shop-app> their role as mediator and self-reacting to changes <app-route>. The value is then on its own page-Attribute transferred. Therefore stand by there selected simply "[[page]]".This enables additional scripting, for example scrolling to the top of the page.

Conclusion

Polymer allows applications to be composed of small, self-contained elements. What has made object-oriented software development so successful can now be found in the DOM. The Twitter hashtag #UseThePlatform chosen by Google also underlines the fact that the approach is simply to use what is available in the browser.

The consistent division of the application into components ultimately plays into the hands of another ambitious Google project - the Progressive Web Apps, which will be dealt with in a second article. (ane)

Music of the future

The upcoming version 2.0 of Polymer will do away with some of the quirks born out of necessity, as Chrome will soon no longer be the only browser that fully supports web components. Anyone who used to be familiar with JavaScript will probably be happy that components can then also be programmed as classes (introduced with ES6).

Stefan Neumann
is a web developer from the very beginning and looks after the in-house shop system at tma pure GmbH. When planning an open source CMS, he takes a closer look at the latest web app trends.

6 comments