π | .gitignore |
π | LICENSE |
π | NOTES.md |
π | README.md |
π | avatar.png |
π | dist |
π | enspiral.png |
π | example.js |
π | index.css |
π | index.html |
π | index.js |
π | package-lock.json |
π | package.json |
π | stuff |
π | test |
luddite.js
hey CampJS VIII
i'm Mikey (@ahdinosaur) from Enspiral
<div class="row">
<a href="http://dinosaur.is.com">
<img alt="Mikey's avatar" src="./avatar.png" width="200" />
</a>
<a href="http://enspiral.com">
<img alt="Enspiral logo" src="./enspiral.png" width="200" />
</a>
</div>
slides are available at http://dinosaur.is/campjs-viii-ludditejs.
???
second time presenting at a conference.
apologies in advance if i disguise any opinions as facts.
what?
luddite.js is a JavaScript framework to make building apps fun again
who are the Luddites?
Luddites are people against centralized technology which decreases quality of life.
what is luddite.js?
a movement against centralized standards which decreases developer experience
what centralized standards?
tc39
a great team advancing the state of the art in JavaScript,
but is one of many possible opinions about JavaScript.
what other opinions?
what if i told you...
that you only needed plain functions and objects?
modules
// randomCat.js
const { random: randomCat } = require('cat-names')
module.exports = randomCat
???
we first create a const
variable from a sync require
function.
we assign the result of this to a global variable module.exports
not the hundred million special syntaxes to import and export es modules
functions
// randomCatAsync.js
const randomCat = require('./randomCat')
module.exports = function randomCatAsync (cb) {
try {
cb(null, randomCat())
} catch (err) {
cb(err)
}
}
---
## sync functions
function fn () { try { return value() } catch (err) {} }
## async functions
### `cb(err, value())
## aids
- [eating your own dog food](https://en.wikipedia.org/wiki/Eating_your_own_dog_food)
- [mad science method](https://github.com/ahdinosaur/mad-science-handbook/blob/master/collaboration.md#the-mad-science-cycle)
- [do-ocracy](https://communitywiki.org/wiki/DoOcracy)
- marathon: keep a slow & steady pace one step at a time
- if you see a job that needs doing, it's your job to do (do-ocrarcy)
- too much sugar is bad for your health (simple interfaces)
## blocks
- cave method: try to design or implement the _perfect_ system before sharing it
- [design by committee](https://en.wikipedia.org/wiki/Design_by_committee)
- sprint: hype, mania, and burn-out
- [waterfall design](https://en.wikipedia.org/wiki/Waterfall_model)
---
# 2009
## nobody cares about JavaScript
> it's a toy language
---
## Ryan Dahl (@ry) creates Node.js
[watch the original presentation](https://www.youtube.com/watch?v=ztspvPYybIY)
> To provide a *purely evented*, *non-blocking* infrastructure to script *highly concurrent* programs.
(original website [here](https://web.archive.org/web/20091003131634/http://nodejs.org/))
???
// core-less node? https://github.com/nodejs/node/issues/7098
// https://github.com/nucleus-js/design
---
## function
```js
function (...args) {
return value
}
module
here's the CommonJS module system, as used and popularized by Node.js
// cat.js
require('cat-names').random
// cat-loop.js
const cat = require('./cat')
setInterval(() => {
console.log(cat())
})
the module wrapper
every module is actually wrapped in a closure
(function (exports, require, module, __filename, __dirname) {
// your module code actually lives in here
})
how require works
When you call
require('some_module')
in node here is what happens:
- if a file called
some_module.js
exists in the current folder node will load that, otherwise:- node looks in the current folder for a
node_modules
folder with asome_module
folder in it- if it doesn't find it, it will go up one folder and repeat step 2
This cycle repeats until node reaches the root folder of the filesystem, at which point it will then check any global module folders (e.g.
/usr/local/node_modules
on Mac OS) and if it still doesn't findsome_module
it will throw an exception.
the Node aesthetic
- Callback austerity: Simplicity, asyncronous nature and nice additions that are included like the event system.
- Limited surface area: Using modules instead of extending them, NPM, re-usable interfaces and simple, consistent function calls.
- Batteries not included: Only few modules in the core distribution β reduces clutter, version dependencies and bureaucracy.
- Radical reusability: Breaking up a problem in small pieces, NPM module locations, great versioning approach
factory
βThe problem with object-oriented languages is theyβve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.β ~ Joe Armstrong
???
TODO two ways of handling errors: throw err and cb(err) how it's important to throw 'programmer errors'
callback
continuable
a "continuable" is a function that takes a single argument, a node-style (error-1st) callback.
const continuable = (cb) => {
// do stuff...
cb(err, data)
}
observable
thing()
gets the valuething.set(...)
sets the valuething(function (value) { ... })
listens to the value.
stream
references
???
TODO luddite.js apps:
Built with git-ssb-web