what the web platform (and your app!) can learn from node.js
TRANSCRIPT
What the web platform can learn from Node.jsand what your web frontend can learn too!
Will Binns-Smith • Frontend Developer, Bitbucket • Atlassian • @wbinnssmith
var request = new XMLHttpRequest();
request.addEventListener("load", function () { console.log(JSON.parse(this.responseText)); }); request.addEventListener("error", function (e) { console.error("oh noes!!"); });
request.open("POST", "http://www.example.org/endpoint"); request.setRequestHeader("Accept", "application/json"); request.setRequestHeader("Content-Type", "application/json"); request.send(JSON.stringify({ my: 'data' }));
POST { my: ‘data’ } to http://example.com/endpoint
$.ajax({ method: "POST", url: "http://example.com/endpoint", data: JSON.stringify({ my: "data" }), contentType: "application/json", dataType: "json", success: () => { console.log(JSON.parse(this.responseText)); }, failure: () => { console.error("oh noes!!"); } });
$.ajax({ method: "POST", url: "http://example.com/endpoint", data: JSON.stringify({ my: "data" }), contentType: "application/json", dataType: "json" }).done(() => { console.log(JSON.parse(this.responseText)); }).fail(() => { console.error("oh noes!!"); });
$.postJSON
POST { my: ‘data’ } to http://example.com/endpoint
var request = require(‘request’);
request.post('http://localhost:3000/endpoint', { json: true, body: { foo: 'bar' } }, (err, resp) => { if (err) throw Error(err); console.log(resp); });
too bad we can’t change XHR without breaking the internet
this happens a lotDOM Mutation Events -> DOM Mutation Observers
Object.observe() -> Proxies, setters
AppCache -> ServiceWorkers
showModalDialog() -> <dialog>, Web Components
a lot of this is preventable.
we need a way to make mistakes and improve upon them
solution: focused modules. from userland.
(and lots of them)
array-union array-uniq camelcase object-assign is-blob … and 761 others on npm
sindresorhus
negative-zero
'use strict'; module.exports = function (x) { return x === 0 && 1 / x === -Infinity; };
sindresorhus
it says what it does, not how to do it (which in JavaScript often makes no sense anyway)
why?
var isNegativeZero = require(‘negative-zero’);
isNegativeZero(5); // false isNegativeZero(-0); // true isNegativeZero(0); // false
sindresorhus
we need tooling for lots and lots of modules. just like we
have in Node
so let’s bring npm to the browser
+
one script tag. (nearly) all of npm.
npm install the-futureObject.assign -> require(‘object-assign’) Promise -> require(‘native-promise-only’) Map -> require(‘es6-map’)
-> require(‘babel-core’) require(‘core-js’)
npm install emojilib{ "100": "💯", "1234": "🔢", "grinning": "😀", "grin": "😁", "joy": "😂", "smiley": "😃", "smile": "😄", "sweat_smile": "😅", "laughing": "😆", "innocent": "😇",
npm install baboon-image-urlmodule.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAACXBIWXMAAAsTAAALEwEAmpwYAAAL
don’t like a module’s API? just npm install a different one
single responsibilities make switching easy
write a module with a terrible API? just fix it and bump the
major version
nobody’s apps break
it’s fearless iteration for your app and your modules
more than
1,000modules in Bitbucket Cloud’s frontend JavaScript alone.
the extensible web manifesto
low-level APIs from the browsers, high-level abstractions from
developers
so why can’t I have request’s API in the browser?
of course you can!
take your pick.
xhr
superagent*
axios*
hyperquest*
nets*
BUT! the web has fetch now!
fetch(‘http://example.com/endpoint', { method: ‘post’, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ my: 'data', }) }).then(response => { return response.json(); }).then(reponse => { console.log(response); });
fetch appears high-level and convenient
but also comes with Request, Response, and WHATWG streams. let’s use these to
build more things!
extend the web forward
one tiny, tiny piece at a time.
npm install thanks --save
Will Binns-Smith • Frontend Developer, Bitbucket • Atlassian • @wbinnssmith