Dominik Lubański
JavaScript Expert, Frontend Architect, and Team Leader with 10+ years of experience in web development. Taking roles in a wide range of projects with software houses, media agencies, rising startups, and other technology companies.
Dominik Lubański
smalluban
source: webcomponents.org
class or this syntax ● complex lifecycle callbacks ● stateful architecture
source: webcomponents.dev
class MyElement extends HTMLElement {
constructor() {
super();
...
}
get text() {
return 'Fresha' || this._text;
}
set text(val) {
this._text = val;
}
someMethod() { ... }
}
customElements.define('my-element', MyElement);
class MyElement extends HTMLElement {}
Object.defineProperty(MyElement.prototype, 'text', {
get: function get() {
return 'Fresha' || this._text;
},
set: function set(val) {
this._text = val;
},
configurable: true,
});
Object.defineProperty(MyElement.prototype, 'someMethod', {
get: () => function someMethod() { ... },
configurable: true,
});
customElements.define('my-element', MyElement);
const MyElement = {
text: {
get: function get() {
return 'Fresha' || this._text;
},
set: function set(val) {
this._text = val;
},
},
someMethod: {
get: () => function someMethod() { ... },
},
};
defineElement('my-element', MyElement);
const MyElement = {
text: {
get: ({ _text }) => 'Fresha' || _text,
set: (host, val) => { host._text = val; },
},
someMethod: {
get: (host) => () => { ... },
},
};
defineElement('my-element', MyElement);
const MyElement = {
text: {
get: (host, lastValue = 'Fresha') => lastValue,
set: (host, newVal, lastValue) => newVal,
},
someMethod: {
get: (host) => () => { ... },
},
};
defineElement('my-element', MyElement);
function myFactory(defaultValue) {
return {
get: (host, lastValue = defaultValue) => lastValue,
set: (host, newVal, lastValue) => newVal,
};
}
const MyElement = {
text: myFactory('Fresha'),
otherText: myFactory('It is super cool!'),
someMethod: {
get: (host) => () => { ... },
},
};
defineElement('my-element', MyElement);
const MyElementOrig = {
text: myFactory('Fresha'),
someMethod: {
get: (host) => () => { ... },
},
};
const MyElementCompact = {
text: 'Fresha',
someMethod: (host) => () => { ... },
};
defineElement('my-element', MyElementCompact);
class MyElement extends HTMLElement {
constructor() {
super();
...
}
get text() {
return 'Fresha' || this._text;
}
set text(val) {
this._text = val;
}
someMethod() { ... }
}
customElements.define('my-element', MyElement);
const MyElement = {
text: 'Fresha',
someMethod: (host) => () => { ... },
};
defineElement('my-element', MyElement);
const GithubStars = {
user: 'hybridsjs',
repo: 'hybrids',
stars: ({ user, repo }) => {
return getGitHubStars(user, repo);
},
render: ({ stars }) => {...},
};
defineElement('github-stars', GithubStars);
render requires stars property
Cache calls stars getter, which requires user and repo properties
Cache calls user and repo getters, and save them as dependencies
of stars getter
Cache returns stars getter result
const GithubStars = {
user: 'hybridsjs',
repo: 'hybrids',
stars: ({ user, repo }) => {
return getGitHubStars(user, repo);
},
render: ({ stars }) => {...},
};
defineElement('github-stars', GithubStars);
render requires stars property
Cache checks if dependencies (user or repo) cache state has changed
Yes - cache clears dependencies, calls stars getter, saves new dependencies and returns result
No - cache returns last calculated stars getter result
import { getGithubStars } from 'github-super-api';
const GithubStars = {
user: 'hybridsjs',
repo: 'hybrids',
stars: ({ user, repo }) => {
return getGithubStars(user, repo);
},
render: renderFactory(({ stars }) => {
// do stuff to update DOM
}),
};
const MyElement = {
propertyName: {
get: (host, lastValue) => {...},
set: (host, newValue, lastValue) => {...},
connect: (host, key, invalidate) => {
// initalize code
return () => {
// clean up code
};
},
observe: (host, value, lastValue) {...},
},
};
import store from './my-redux-store';
function connect(store, mapState) {
return {
get: mapState
? () => mapState(store.getState())
: () => store.getState(),
connect: (host, key, invalidate) => {
return store.subscribe(invalidate);
},
};
};
const MyElement = {
value: connect(store, ({ value }) => value),
};
npm i hybrids
By Dominik Lubański
Internal presentation for the Fresha team folks about my hybrids library based on a presentation created for ConFrontJS 2018.
JavaScript Expert, Frontend Architect, and Team Leader with 10+ years of experience in web development. Taking roles in a wide range of projects with software houses, media agencies, rising startups, and other technology companies.