Friday, August 14, 2015

Client-side HTML imports: Tip of the web components iceberg!

Here's yet another article for a very simple and common use case for one of the web-components and a sneak peek into all the other exciting possibilities. Web components unfortunately aren't supported even by modern browsers with the exception of Chrome. But... fortunately for us who want to push the boundaries of web, of course there are polyfills, so continue reading!

What are web components?

I think two of these definitions give a good overview of what web-components are:
"Web Components consists of several separate technologies. You can think of Web Components as reusable user interface widgets that are created using open Web technology. They are part of the browser and so they do not need external libraries like jQuery or Dojo. An existing Web Component can be used without writing code, simply by adding an import statement to an HTML page. Web Components use new or still-developing standard browser capabilities".
MDN

"Web Components are a set of standards currently being produced by Google engineers as a W3C specification that allow for the creation of reusable widgets or components in web documents and web applications. The intention behind them is to bring component-based software engineering to the World Wide Web. The components model allows for encapsulation and interoperability of individual HTML elements."
Wikipedia

Here is a very simple use case for one of the basic web-components:

Let's say you have many templates, components which share a header, nav, footer, search or some other reusable component... Frankly there isn't much of an issue in the context of a web-application or a server-side techology if you want to include and reuse those and you would resort to one of these many ways: "include", "import", "partial" "embed" whatever you call it, based on the server-side or client-side stack you're using (obvious from their nomenclature), the very basic and simple of them being the server-side includes, usable even on a static set of pages, without even the need to have the .shtml extension. So you ask, then what's the problem? But just think about it... shouldn't an age-old technology of including a basic reusable component/module be part of the basic HTML standards,  inherent of HTML, without needing additional client-side or server-side scripting or having to run on a server?

Yes, there is, and that's just one example of web components, the HTML import (code below)! As simple as it should be, but it doesn't work everywhere,  out of the box! Yes, this is dated as of 8/2015!

Apparently Chrome supports web components the best, but it doesn't render HTML imports locally even with a Node http server. So there you go! so near, yet so far!

<head>
  <link rel="import" href="/yourincludesfolder/nav.html">
</head>

So how would we approach this now, outside of a web-app? 


Let's say I am working on a static set of HTML.CSS, JS pages/front-end prototypes, one of the common patterns of front-end development that is becoming part and parcel of many workflows.

In a simple case of Brackets IDE (if I may call it that), that runs on an integrated Node JS process and hence has a "built-in" local server, one would think that it would be obviously be able to run a simple server-side include. But not yet, although it seems to be in the works.

https://github.com/adobe/brackets/issues/8277

If you have Node installed globally,  you would think you'd automatically have the http server. But no, you need to install it. OK, fine, you install and run the Node Http server in your project directory and then you'd be able to have a simple SSI? Wrong again! Node http server doesn't recognize SSIs or includes.

OK, we see there is an SSI parser for Node, let's install that for our project...

npm install ssi

You'd think, Ta Da! Nope, nothing automagic yet... with some more work/"pain" you can perhaps make SSI work or use Express JS and what not, but all I need is a freakin include!

So I say, fuhgeddaboutit! Just install MAMP locally and move on! And I did.

Install MAMP; change the httpd.conf or .htaccess file (rather just uncomment) to be able to recognize SSI, and if you'd rather use them with just .html and not .shtml, add below and you're done!

AddHandler server-parsed .html
AddHandler server-parsed .htm

Easy, peasy? Yes, but obviously after the above long suffering paragraph, that's not the point that I am trying to make here. Shouldn't having an include be more basic than that? 

We don't have to need JS application frameworks or server-side technologies or anything much else for an include and this is just the tip of the iceberg of what's possible with web components. They help us build reusable, stand-alone Web-UI widgets that are platform, framework agnostic and portable into any technology/platform. With frameworks coming up like the flavor of the day these days... Angular, React, Ember, Backbone, Node... and many organizations taking the Atomic Design, pattern-library approach, it makes perfect sense to have a componential approach to building encapsulated Web-UI widgets, eg. an accordion, image slider, alerts, ratings, comparison tables, video player, calendar or a custom flex elements to name a few and web-components make this possible. They also offer data-binding and exist outside of the application layer, hence separating the UI (front-end) and application concerns.

It seems like the picture is quite rosy so far, but some of the cons could be the other side of the encapsulation aspect of the scoped CSS (within the shadowDOM of the widgets), but if you are UI widgets reusing within your own organization, that should not be much of an issue except during re-branding perhaps in which case you'd probably be overhauling more than just CSS. Although I haven't used web components yet, the other cons I have come across seem more like the growing pain aspects of web-components, browser issues, polyfills/libraries slowness and such.  

I hope more browsers natively support web components soon... until then we have polyfills and Polymer (see below), although that is counter-intuitive to the very premise of web-components!

Here's a more detailed article by Lea Verou (representative of perhaps many more) with similar thoughts and more links to what web components are, can do and how you can use them now.

http://lea.verou.me/2012/01/what-we-still-can%E2%80%99t-do-client-side/

http://www.html5rocks.com/en/tutorials/webcomponents/imports/#deliver-webcomponents

http://caniuse.com/#feat=imports

If you get disheartened by the above link, don't miss the resources below.

http://webcomponents.org/  (from the horse's mouth)

https://www.polymer-project.org/1.0/

I highly recommend watching the video below from the Polymer folks at Chrome which is quite encouraging, not to mention the lightest version of the library is currently just 19K and good to hear that performance is getting better with every version.
http://webcomponents.org/presentations/componentize-your-app-with-polymer-elements/

https://www.polymer-project.org/1.0/docs/start/getting-the-code.html#project-setup

https://css-tricks.com/modular-future-web-components/ (no article can be complete w/out a CSS tricks reference!)

https://customelements.io/ (get inspired).

http://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/