cristiano betta (betta works) - lightweight libraries with rollup, riot and redux

Post on 10-Apr-2017

216 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

LIGHTWEIGHT JSwith Rollup, Riot and Redux

Cristiano Betta

| @cbetta betta.io

CRISTIANO BETTAHacker @ betta.io

@cbetta

2x @ Techsylvania!

ex-PayPal/Braintree

Ruby/JS Developer

Director @ Work Betta

Founder @ punch.rocks

 

PUNCH <script src="punch.js" charset="utf-8"></script>

<div id='registration'></div>

<script type="text/javascript"> punch.setup({ id: "19acb1ab...53fd459280d", type: 'popover', element: '#registration' }); </script>

 

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

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

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

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 <script src="punch.js" charset="utf-8"></script>

<div id='registration'></div>

<script type="text/javascript"> punch.setup({ id: "19acb1ab...53fd459280d", type: 'popover', element: '#registration' }); </script>

 

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)

REACT JSA Javascript Library for building user

interfaces

facebook.github.io/react

~146kb (compressed)

RIOTA React-like user interface micro-library

riotjs.com

~9.18kb (compressed)

RIOTA React-like user interface micro-library

Custom Tags

Virtual Dom

Enjoyable Syntax

No IE8 support

Tiny Size!

RIOT<!-- index.html --> <div id='element'></div>

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

import riot from 'riot';

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

RIOT<!-- punch-dropin.tag --> <punch-dropin> <h1>Hello World</h1> </punch-dropin>

RIOT<!-- punch-dropin.tag --> <punch-dropin> <punch-loader></punch-loader> <punch-form></punch-form> </punch-dropin>

 

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!!!

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<!-- punch-dropin.tag --> <punch-dropin> <h1>Counter: { state.count }</h1>

<script type="text/javascript"> this.mixin('redux');

this.subscribe(function(state){ this.state = state; }.bind(this)) </script> </punch-dropin>

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<!-- punch-dropin.tag --> <punch-dropin> <h1 onClick={ increment }>Counter: { state.count }</h1>

<script type="text/javascript"> this.mixin('redux');

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

this.subscribe(function(state){ this.state = state; }.bind(this)) </script> </punch-dropin>

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

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

top related