Ve prospěch mikro-frameworků
Hyperapp

Kdo jsem

Moje Front-end historie

  1. jQuery + Silverlight (RIP 2015)
  2. AngularJS (RIP 2016)
  3. JavaScriptová únava

Protože

ES6, ES2016, Babel, TypeScript, JSX,
Node.js, NPM, WebPack, Gulp, Grunt,
React, Redux, Angular, Vue.js, Ember, Mithril

Protože

Co jsem chtěl - moderní framework

Co jsem nechtěl

Hyperapp to the rescue

Proč? - Protože

  1. Má, co jsem chtěl
  2. Nemá, co jsem nechtěl
  3. A zvládne to na 403 řádách kódu včetně prázných - 2kB
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.hyperapp={})}(this,function(e){"use strict";e.h=function(e,n){for(var t=[],r=[],o=arguments.length;o-- >2;)t.push(arguments[o]);for(;t.length;){var u=t.pop();if(u&&u.pop)for(o=u.length;o--;)t.push(u[o]);else null!=u&&!0!==u&&!1!==u&&r.push(u)}return"function"==typeof e?e(n||{},r):{nodeName:e,attributes:n||{},children:r,key:n&&n.key}},e.app=function(e,n,t,r){var o,u=[].map,i=r&&r.children[0]||null,l=i&&function e(n){return{nodeName:n.nodeName.toLowerCase(),attributes:{},children:u.call(n.childNodes,function(n){return 3===n.nodeType?n.nodeValue:e(n)})}}(i),f=[],a=!0,c=p(e),s=function e(n,t,r){for(var o in r)"function"==typeof r[o]?function(e,o){r[e]=function(e){var u=o(e);return"function"==typeof u&&(u=u(y(n,c),r)),u&&u!==(t=y(n,c))&&!u.then&&h(c=m(n,p(t,u),c)),u}}(o,r[o]):e(n.concat(o),t[o]=p(t[o]),r[o]=p(r[o]));return r}([],c,p(n));return h(),s;function d(e){return"function"==typeof e?d(e(c,s)):null!=e?e:""}function v(){o=!o;var e=d(t);for(r&&!o&&(i=function e(n,t,r,o,u){if(o===r);else if(null==r||r.nodeName!==o.nodeName){var i=function e(n,t){var r="string"==typeof n||"number"==typeof n?document.createTextNode(n):(t=t||"svg"===n.nodeName)?document.createElementNS("http://www.w3.org/2000/svg",n.nodeName):document.createElement(n.nodeName),o=n.attributes;if(o){o.oncreate&&f.push(function(){o.oncreate(r)});for(var u=0;u<n.children.length;u++)r.appendChild(e(n.children[u]=d(n.children[u]),t));for(var i in o)b(r,i,o[i],null,t)}return r}(o,u);n.insertBefore(i,t),null!=r&&k(n,t,r),t=i}else if(null==r.nodeName)t.nodeValue=o;else{!function(e,n,t,r){for(var o in p(n,t))t[o]!==("value"===o||"checked"===o?e[o]:n[o])&&b(e,o,t[o],n[o],r);var u=a?t.oncreate:t.onupdate;u&&f.push(function(){u(e,n)})}(t,r.attributes,o.attributes,u=u||"svg"===o.nodeName);for(var l={},c={},s=[],v=r.children,h=o.children,m=0;m<v.length;m++){s[m]=t.childNodes[m];var y=g(v[m]);null!=y&&(l[y]=[s[m],v[m]])}for(var m=0,N=0;N<h.length;){var y=g(v[m]),w=g(h[N]=d(h[N]));if(c[y])m++;else if(null==w||a)null==y&&(e(t,s[m],v[m],h[N],u),N++),m++;else{var x=l[w]||[];y===w?(e(t,x[0],x[1],h[N],u),m++):x[0]?e(t,t.insertBefore(x[0],s[m]),x[1],h[N],u):e(t,s[m],null,h[N],u),c[w]=h[N],N++}}for(;m<v.length;)null==g(v[m])&&k(t,s[m],v[m]),m++;for(var m in l)c[m]||k(t,l[m][0],l[m][1])}return t}(r,i,l,l=e)),a=!1;f.length;)f.pop()()}function h(){o||(o=!0,setTimeout(v))}function p(e,n){var t={};for(var r in e)t[r]=e[r];for(var r in n)t[r]=n[r];return t}function m(e,n,t){var r={};return e.length?(r[e[0]]=e.length>1?m(e.slice(1),n,t[e[0]]):n,p(t,r)):n}function y(e,n){for(var t=0;t<e.length;)n=n[e[t++]];return n}function g(e){return e?e.key:null}function N(e){return e.currentTarget.events[e.type](e)}function b(e,n,t,r,o){if("key"===n);else if("style"===n)for(var u in p(r,t)){var i=null==t||null==t[u]?"":t[u];"-"===u[0]?e[n].setProperty(u,i):e[n][u]=i}else"o"===n[0]&&"n"===n[1]?(n=n.slice(2),e.events?r||(r=e.events[n]):e.events={},e.events[n]=t,t?r||e.addEventListener(n,N):e.removeEventListener(n,N)):n in e&&"list"!==n&&!o?e[n]=null==t?"":t:null!=t&&!1!==t&&e.setAttribute(n,t),null!=t&&!1!==t||e.removeAttribute(n)}function k(e,n,t){function r(){e.removeChild(function e(n,t){var r=t.attributes;if(r){for(var o=0;o<t.children.length;o++)e(n.childNodes[o],t.children[o]);r.ondestroy&&r.ondestroy(n)}return n}(n,t))}var o=t.attributes&&t.attributes.onremove;o?o(n,r):r()}}});

Apka 1/5 - import

const { h, app } = hyperapp

Apka 2/5 - stav

const state = { count: 0 }

Apka 3/5 - akce

const actions = {
    up: value => state => ({ count: state.count + value })
}

Apka 4/5 - view

const view = (state, actions) => (
    h('button', { onclick: () => actions.up(1) }, state.count)
)

Apka 5/5 - spustit

app(state, actions, view, document.body)

Nečekané výhody

Další podobné případy

LiteDB - 345 kB

Doporučení nakonec

Writing Less Damned Code – Heydon Pickering – btconfBER2016

Děkuji