Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and Redux

download Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and Redux

of 53

  • date post

    10-Apr-2017
  • Category

    Technology

  • view

    205
  • download

    1

Embed Size (px)

Transcript of Cristiano Betta (Betta Works) - Lightweight Libraries with Rollup, Riot and Redux

  • LIGHTWEIGHT JSwith Rollup, Riot and Redux

    Cristiano Betta

    | @cbetta betta.io

    https://twitter.com/cbettahttps://betta.io/

  • CRISTIANO BETTAHacker @ betta.io

    @cbetta

    https://betta.io/https://twitter.com/cbetta

  • 2x @ Techsylvania!

    ex-PayPal/Braintree

    Ruby/JS Developer

    Director @ Work Betta

    Founder @ punch.rocks

  • PUNCH

    punch.setup({ id: "19acb1ab...53fd459280d", type: 'popover', element: '#registration' });

  • PROBLEMS1. I am not a hardcore JS Dev2. How to make a browser library?3. How to maintain state?4. How to update the UI?5. How to not go crazy while doing it?

  • THIS TALK1. Learn some JS!2. Bundling3. State Management Libraries4. UI Management Libraries5. Occasional Cat Pictures

  • BUNDLINGNodeJS dependencies in the bowser

  • BROWSERIFYBrowserify lets you require('modules') in

    the browser by bundling up all of yourdependencies.

    Browserify.orgbrowserify main.js -o bundle.js

    Older

    JS Only

    No ES6 import/export

    Not the smallest result

    http://browserify.org/

  • WEBPACKA bundler for javascript and friends.

    webpack.github.iowebpack input.js output.js

    Newer

    Handles many assets

    No ES6 import/export

    Not always smallest result

    Not the simplest

    https://webpack.github.io/

  • ROLLUPThe next-generation JavaScript module

    bundler

    rollupjs.orgrollup input.js --output output.js

    Newer

    JS Only

    No ES6 import/export

    Tree shaking

    Simple to use

    https://rollupjs.org/

  • ROLLUPThe next-generation JavaScript module

    bundler

    Write ES6 (aka ES2015)

    Bundle into single file

    Smaller than Browserify and Webpack

    Export to AMD, CommonJS, ES2015, Globals, UMD

    Tree shaking!

  • ES6import fs from 'fs';

    class AwesomeSauce { constructor() { // some code }

    makeIt() { // some code } }

    export default AwesomeSauce;

  • ES6import AwesomeSauce from 'awesome-sauce';

    let sauce = new AwesomeSauce(); sauce.makeIt();

  • ES6class AwesomeSauce { // 100 lines of code }

    class EnterpriseSauce { // 2000 lines of code }

    export EnterpriseSauce; export default AwesomeSauce;

  • ES6//import 2000 lines of code! import { EnterpriseSauce } from 'awesome-sauce';

    let sauce = new EnterpriseSauce(); sauce.makeItSecureButSlow();

  • ROLLUP TREE SHAKING// main.js import { cube } from './maths.js'; console.log( cube( 5 ) );

    // maths.js

    // unused function export function square ( x ) { return x * x; }

    // included function export function cube ( x ) { return x * x * x; }

  • ROLLUP TREE SHAKINGfunction cube ( x ) { return x * x * x; }

    console.log( cube( 5 ) );

  • ROLLUP UMD(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); }(this, function () { 'use strict'; function cube ( x ) { return x * x * x; }

    console.log( cube( 5 ) ); }));

  • NPM// package.json { ... "scripts": { "dist:js": "rollup -c rollup/dist.js", ... } }

  • NPM// rollup/dist.js

    export default { entry: 'js/index.js', dest: 'dist/punch.js', format: 'umd', moduleName: 'punch', plugins: [ riot(), npm({ browser: true }), commonjs(), babel(), uglify() ] };

  • NPM// js/index.js

    import Dropin from './dropin/main.js';

    let dropin = new Dropin();

    export var setup = dropin.setup; // punch.setup() from earlier! export var destroyAll = dropin.destroyAll; export var instances = dropin.instances;

  • PUNCH

    punch.setup({ id: "19acb1ab...53fd459280d", type: 'popover', element: '#registration' });

  • UI MANAGEMENTNothing can be said to be certain

    except death and taxes

    and JS frameworks

  • ANGULAR JSHTML enhanced for web apps!

    angularjs.org

    ~50kb (compressed)

    https://angularjs.org/

  • REACT JSA Javascript Library for building user

    interfaces

    facebook.github.io/react

    ~146kb (compressed)

    https://facebook.github.io/react/

  • RIOTA React-like user interface micro-library

    riotjs.com

    ~9.18kb (compressed)

    http://riotjs.com/

  • RIOTA React-like user interface micro-library

    Custom Tags

    Virtual Dom

    Enjoyable Syntax

    No IE8 support

    Tiny Size!

  • RIOT

    // dropin.js import './tags/punch-dropin.tag';

    import riot from 'riot';

    riot.mount('#element', "punch-dropin");

  • RIOT Hello World

  • RIOT

  • STATE MANAGEMENTThere are two hard things in computer science: cache

    invalidation and naming things.

    There are two hard things in computer science: cacheinvalidation and naming things and state management

    There are three hard things in computer science: cacheinvalidation and naming things and state management

    There are two hard things in computer science: cacheinvalidation, naming things and state management

  • REDUXRedux is a predictable state container for

    JavaScript apps.

    github.com/reactjs/redux

    2kb

    Including dependencies!

    Before uglifying/compression!!

    Riot compatible!!!

    https://github.com/reactjs/redux

  • REDUXnpm install redux

    // dropin.js import './tags/punch-dropin.tag';

    import riot from 'riot'; import { createStore } from 'redux'; import StoreMixin from 'riot-redux-mixin';

    let state = ... let store = createStore(state); riot.mixin('redux', new StoreMixin(store));

    riot.mount('#element', "punch-dropin");

  • REDUX Counter: { state.count }

    this.mixin('redux');

    this.subscribe(function(state){ this.state = state; }.bind(this))

  • REDUX// dropin.js

    let state = function counter(count = 0, action) { switch (action) { case 'increment': return count + 1 case 'decrement': return count - 1 default: return count }

  • REDUX Counter: { state.count }

    this.mixin('redux');

    this.increment = function() { this.store.dispatch('increment'); }

    this.subscribe(function(state){ this.state = state; }.bind(this))

  • DEMO

  • COMPARISONAll results in bytes, Gzipped

    babel + browserify + uglify => 3915

    webpack@2 + babel + uglify => 3632

    babel + rollup + uglify => 3440

    typescript + webpack => 3245

    closure => 2890

  • COMPARISONMore results

    github.com/samccone/The-cost-of-transpiling-es2015-in-2016

    https://github.com/samccone/The-cost-of-transpiling-es2015-in-2016

  • MY RESULTSsource - 37,304 bytes

    bundled => 180,345 bytes (100%)

    uglified => 57,171 bytes (31%)

    gzipped => 18,561 bytes (10%)

  • CONCLUSIONSMost of these are personal opinion

    ES6 is lovely

    RiotJS is easy and really small

    Riot+Redux makes apps easy to comprehend

    Rollup + NPM scripts beats Gulp and Grunt

  • NOTESSome stuff isn't there yet

    Rollup+Riot breaks sourcemaps

    Riot Routes needs to be added

    Hard to scientifically compare sizes

  • QUESTIONS?Cristiano Betta | | @cbetta betta.io

    go.betta.io/lightweightjs

    https://twitter.com/cbettahttps://betta.io/http://go.betta.io/lightweightjs