Web Components
can do that ?!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6231863/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6267206/Capture_d_écran_2019-06-18_à_00.30.09.png)
Why
Web Components ?
a very big company
🖥 Many applications
🛠 Many technologies
👥 Many teams
Need consistency
Need interoperability
Need stability
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6251697/pasted-from-clipboard.png)
In big companies
At an UI level
A Design system
👇🏼
In big companies
At a technical level
Web components
👇🏼
Framework
Web components
orchestrate
plays
Agenda
2.
Use cases
3.
What is next ?
1.
The 4 trends for Web Components
Vincent Ogloblinsky
Frontend software architect
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/3581264/logo-sii-big-bordered.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/3581796/GitHub-Mark-32px-white.png)
The
4 trends
for
Web Components
Librairies
Compilers
Backporters
Framework
Librairies
2 approaches :
class based
functional based
Librairies - Class based
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6231979/pasted-from-clipboard.png)
import {
LitElement,
html,
property,
customElement
} from 'lit-element';
@customElement('simple-greeting')
export class SimpleGreeting extends LitElement {
@property() name = 'World';
render() {
return html`<p>Hello, ${this.name}!</p>`;
}
}
<simple-greeting name="Everyone"></simple-greeting>
Librairies - Class based
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6231984/pasted-from-clipboard.png)
import {Slim} from 'slim-js'
import {
tag,
template,
attribute
} from 'slim-js/Decorators'
@tag('simple-greeting')
@template('<p>Hello, {{name}}!</p>')
class MyTag extends Slim {
@attribute
name
}
<simple-greeting name="Everyone"></simple-greeting>
Librairies - Functional based
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6231986/pasted-from-clipboard.png)
import
Element, { html }
from '@skatejs/element-lit-html';
export default class extends Element {
static get props() {
return {
name: String
};
}
render() {
return html`
<p>Hello, ${this.name}!</p>
`;
}
}
<simple-greeting name="Everyone"></simple-greeting>
Librairies - Functional based
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6231990/pasted-from-clipboard.png)
import { html, define } from 'hybrids';
export const HelloWorld = {
name: '',
render: ({ name }) => html`
<p>Hello, ${name}</p>
`,
};
define('simple-greeting', HelloWorld);
<simple-greeting name="Everyone"></simple-greeting>
Framework
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232025/pasted-from-clipboard.png)
import { define, WeElement, html, render } from 'omi'
define('simple-greeting', class extends WeElement {
render(props) {
return html`<p>{props.text}</p>`
}
});
<simple-greeting name="Everyone"></simple-greeting>
Compilers
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232021/pasted-from-clipboard.png)
<!-- simple-greeting.riot -->
<p>{ props.message }</p>
import { register, mount, component } from 'riot';
import simpleGreeting from './simple-greeting.riot';
// register the my-component as global component
register('simple-greeting', simpleGreeting);
// find all the DOM nodes called `<simple-greeting>` and
// mount them with the component previously registered
mount('simple-greeting');
<simple-greeting name="Everyone"></simple-greeting>
Compilers
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232016/pasted-from-clipboard.png)
<p>{name}</p>
<script>
export default {
tag: 'simple-greeting',
props: ['name']
}
</script>
/**
* -> Compile it with Svelte CLI
*/
<simple-greeting name="Everyone"></simple-greeting>
Compilers
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232019/pasted-from-clipboard.png)
import { h, Component, Prop } from '@stencil/core';
@Component({
tag: 'simple-greeting'
})
export class SimpleGreeting {
@Prop() name: string;
render() {
return <p>{this.name}</p>;
}
}
<simple-greeting name="Everyone"></simple-greeting>
Backporters
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232028/pasted-from-clipboard.png)
import { Component, Input } from '@angular/core';
@Component({
selector: 'simple-greeting',
template: `
<p>{{ name }}</p>
`
})
export class SimpleGreeting {
@Input() name: string;
}
<simple-greeting name="Everyone"></simple-greeting>
import { ɵrenderComponent } from '@angular/core';
import { SimpleGreeting } from './simple-greeting.component';
export class SimpleGreetingElement extends HTMLElement {
private comp: SimpleGreeting;
constructor() {
super();
this.comp = ɵrenderComponent(SimpleGreeting, { host: this });
}
}
Backporters
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232039/pasted-from-clipboard.png)
<template>
<p>{name}</p>
</template>
<script>
export default {
name: 'SimpleGreeting',
props: ['name']
}
</script>
/**
* -> Compile it with Vue CLI
*/
<simple-greeting name="Everyone"></simple-greeting>
Backporters
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232042/pasted-from-clipboard.png)
import { WidgetBase } from '@dojo/framework/widget-core/WidgetBase';
import customElement from '@dojo/framework/widget-core/decorators/customElement';
import { v } from '@dojo/framework/widget-core/d';
import { ThemedMixin } from '@dojo/framework/widget-core/mixins/Themed';
@customElement({
tag: 'simple-greeting',
events: [],
attributes: ['name'],
properties: []
})
export default class SimpleGreeting extends ThemedMixin(WidgetBase) {
protected render() {
const { name } = this.properties;
return v('s', {}, [name]);
}
}
/**
* -> Compile it with Dojo CLI
*/
<simple-greeting name="Everyone"></simple-greeting>
Backporters
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232053/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232057/pasted-from-clipboard.png)
Benchmark
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244871/vogloblinsky.github.io_web-components-benchmark___1_.png)
Make a choice
Warning !
Take care of Developer eXperience (DX)
versus
User eXperience (UX)
Use-cases
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6232063/radiance-design-system-akshaysalekar.png)
1 - Design System
Centralized library of components that can be shared across teams and projects to simplify design and development while ensuring consistent brand experiences, at scale.
Design System
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239712/pasted-from-clipboard.png)
Design System - Advantages
📉 Design debt
📉🤜🏻🤛🏻 Collaboration and communication problems
📉 Repetitive work
Consistency within a product family
Design System - Examples
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6238184/canvas.hubspot.com_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239783/lightningdesignsystem.com_.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239796/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239806/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239811/atlassian.design_.png)
Design System - How to ?
Balance consistency with flexibility
Component describes visual language & functional behavior
Journey which designers and developers take together
Design System - How to ?
Code with Web Components
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239904/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239905/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239909/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239912/pasted-from-clipboard.png)
...
Design System - How to ?
Tooling with open-wc
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244882/open-wc.org_.png)
Design System - How to ?
Documentation with Storybook
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239894/clever-banach-415c03.netlify.com__path__story_tasklist--default.png)
Design System - How to ?
Share them with
Bit or npm
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6239861/bit.dev_features.png)
2 - Standalone widget
3 - Framework migration
Most of the time
⛪️ Catholic wedding with framework
🏗 Architecture is based on a framework
Framework migration
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244906/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244909/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244913/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244916/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244918/pasted-from-clipboard.png)
?
?
?
?
Framework migration
2 strategies :
💣 Big bang
🏗 Incremental
Framework migration
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244906/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244909/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244913/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244916/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244918/pasted-from-clipboard.png)
WC
WC
WC
WC
Framework migration
Web component integration
Migrate existing component to WC
Check your framework's WC support
Framework migration
Check framework WC support
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244945/custom-elements-everywhere.com_.png)
Framework migration
Feedbacks from companies
Warning on internal UI libraries and compatibility
Transition time between old & new screen
Stop coupling a lot
It just "works"
4 - Micro frontends
The idea behind Micro Frontends is to think about a website or web app as a composition of features which are owned by independent teams. Each team has a distinct area of business or mission it cares about and specialises in. A team is cross functional and develops its features end-to-end, from database to user interface. (micro-fontend.org)
Micro frontends
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6244959/pasted-from-clipboard.png)
Micro frontends
Strategies
Fragment concept (Zalando) - Project Mosaic
Single-spa - Framework which connects frameworks with iframes
Web Components
Micro frontends
Starting questions
How big is your application in terms of team and code ?
Can you divide your app into small pieces by domain accessory ?
How easy can you release small features for your application ?
What's next ?
Move from static to dynamic template, also during update
<template id="person">
<section>
<h1>{{name}}</h1>
Email: <a href="mailto:{{email}}">{{email}}</a>
</section>
</template>
let template = document.querySelector('#person');
let instance = template.createInstance({
name: "Ryosuke Niwa",
email: "rniwa@webkit.org"
});
CSS Shadow parts
Style elements inside Shadow DOM
<x-foo>
#shadow-root
<div part="some-box"><span>...</span></div>
<input part="some-input">
<div>...</div> /_ not styleable _/
</x-foo>
x-foo::part(some-box) { ... }
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6241688/pasted-from-clipboard.png)
Chrome 74
Create stylesheet objects from script & remove the need for declarative style elements
const myElementSheet = new CSSStyleSheet();
class MyElement extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.adoptedStyleSheets = [myElementSheet];
}
connectedCallback() {
if (myElementSheet.cssRules.length == 0) {
myElementSheet.replaceSync(styleText);
}
}
}
ECMAScript 6 native module for HTML & CSS
<script type="module">
import {content} from "import.html"
document.body.appendChild(content);
</script>
<div id="blogPost">
<p>Content...</p>
</div>
<script type="module">
let blogPost = import.meta.document.querySelector("#blogPost");
export {blogPost}
</script>
ECMAScript 6 native module for HTML & CSS
import {content} from "import.html"
import styles from './styles.css';
class MyElement extends HTMLElement {
constructor() {
this.attachShadow({mode: open});
// push() doesn't actually exist yet
this.shadowRoot.moreStyleSheets.push(styles);
this.shadowRoot.appendChild(content);
}
}
![](https://s3.amazonaws.com/media-p.slid.es/uploads/573039/images/6241688/pasted-from-clipboard.png)
Chrome 73
Namespacing for Custom Element definition
// Create a new registry that inherits from the global registry
const myRegistry = new CustomElementRegistry(window.customElements);
// Use the local registry when creating the ShadowRoot
element.attachShadow({mode: 'open', customElements: myRegistry});
// Define a trivial subclass of XFoo so that we can register it ourselves
class MyFoo extends XFoo {}
// Register it as `my-foo` locally.
myRegistry.define('my-foo', MyFoo);
// the definiton of my-foo will be resolved from the custom registry
const myFoo = this.shadowRoot.createElement('my-foo');
element.shadowRoot.appendChild(myFoo);
Conclusion
Analyze your application(s)
Start small, mix 1 by 1
Choose the correct scope of your WC(s)
Take care of performance issues
Automate everything
Resources
9 Web Components UI Libraries You Should Know in 2019
https://blog.bitsrc.io/9-web-component-ui-libraries-you-should-know-in-2019-9d4476c3f103
Stencil for Production design systems
Constructable Stylesheets - Chrome 73
https://developers.google.com/web/updates/2019/02/constructable-stylesheets
Resources
Design Systems Should be JavaScript Framework Agnostic
https://hackernoon.com/design-systems-should-be-javascript-framework-agnostic-2a0c47129ec8
UI in Microservices World — Micro Frontends pattern and Web Components
Keep It Simple Stupid
#UseThePlatform
Thanks for listening !
Ask me anything
Slides : bit.ly/wc-can-do-that
Web Components can do that ?
By Vincent Ogloblinsky
Web Components can do that ?
- 3,692