Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Off the Rails
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Danielle Smith
March 17, 2017
Programming
40
0
Share
Off the Rails
My journey to becoming a
~hipster~ Node.js developer
Danielle Smith
March 17, 2017
More Decks by Danielle Smith
See All by Danielle Smith
Ruby Ruby
daninithepanini
0
150
A Brief History of Ruby
daninithepanini
0
45
Static Type Inferencing ... in Ruby?
daninithepanini
0
27
Action Game
daninithepanini
0
40
RubyGL
daninithepanini
0
31
YeSQL
daninithepanini
0
28
Game Dev in Ruby
daninithepanini
0
40
Euler vs Hamilton
daninithepanini
0
45
Other Decks in Programming
See All in Programming
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
1
130
サプライチェーン攻撃対策「層を重ねて落ちない壁」を10日間で組み上げた話 #TechLeadConf2026
kashewnuts
1
290
Skillは並べた。動かなかった。契約で繋いだ。— 65個のSkillから、自走する開発サイクルへ
junholee
0
610
検索設計から 推論設計への重心移動と Recall-First Retrieval
po3rin
5
1.7k
ふにゃっとしない名前の付け方 〜哲学で茹で上げる、コシのあるソフトウェア設計〜
shimomura
0
120
WebAssembly を読み込むベストプラクティス 2026年春版 / Best Practices for Loading WebAssembly (Spring 2026)
petamoriken
5
1.1k
AIベース静的検査器の偽陽性率を抑える工夫3選
orgachem
PRO
4
460
空間オーディオの活用
objectiveaudio
0
150
実践ハーネスエンジニアリング:ステアリングループを実例から読み解く / Practical Harness Engineering: Understanding Steering Loops Through Real-World Examples
nrslib
5
5.5k
書籍「ユーザーストーリーマッピング」が私のバイブル
asumikam
4
490
Terraform言語の静的解析 / static analysis of Terraform language
wata727
1
150
KMP × Kotlin 2.3 - How Android Got Slower While iOS Builds Improved by 47%
rio432
0
200
Featured
See All Featured
Building Adaptive Systems
keathley
44
3k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
300
A Modern Web Designer's Workflow
chriscoyier
698
190k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
360
Test your architecture with Archunit
thirion
1
2.2k
Thoughts on Productivity
jonyablonski
76
5.2k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.1k
AI: The stuff that nobody shows you
jnunemaker
PRO
7
640
The Cost Of JavaScript in 2023
addyosmani
55
9.9k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Between Models and Reality
mayunak
4
290
Transcript
Off the Rails My journey to becoming a hipster Node.js
developer
Hi, I’m Dan
Ruby is my first love
But I got into an affair with Node.js
Temptation
Client said they had “experience”
(also didn’t seem to like ruby for some reason)
But what the heck, Node.js is the new hotness, right?
None
First rule of node.js -
THERE ARE NO RULES!
Seeing a node.js project for the first time
Controllers?
Express.js !
Models?
Find an ORM that works!
Views?
$ mkdir views $ vim views/index.jade
No Black Magic
Just raw, naked programming
Make your OWN conventions
None
“What happens server-side, stays server side” Problem?
Scenario: Developer A types in a ‘console.log’
Developer B: “where is that going to show up?”
Developer B: “where is that going to show up?” Developer
A: “in the server log”
Developer B: “where is that going to show up?” Developer
A: “in the server log” Developer B: “okay cool”
Developer B: “where is that going to show up?” Developer
A: “in the server log” Developer B: “okay cool” both devs watch the server log for some time
Developer B: “where is that going to show up?” Developer
A: “in the server log” Developer B: “okay cool” both devs watch the server log for some time Developer A: “No wait, there it is in Chrome’s devtools"
Familiar (but different)
npm / bundler
gulp / rake
ndenv / rbenv
mocha / rspec
jade / slim
Express.js / sinatra
Sequelize / ActiveRecord (almost)
factory-girl / factory-girl
Going so fast!
WHY SO SYNCHRONOUS?
Errorbacks
Errorbacks
The anatomy of an ‘errorback’ function(error, results…)
The anatomy of an ‘errorback’ function(error, results…) the result(s) of
the function taking the callback
The anatomy of an ‘errorback’ function(error, results…) this is non-null
if there was an error the result(s) of the function taking the callback
foo(42, function(err, result) { // happens “later” if (err) {
console.error(err.message); } else { console.log(result); } }); // happens immediately ...
Seems innocent enough until ...
Callback Hell
foo(42, function(err, fooResult) { if (!err) { bar(fooResult, function(err, barResult)
{ if (!err) { baz(barResult, function(err, bazResult) { if (!err) { qux(bazResult, function(err, quxResult) { if (!err) { norf(quxResult, function(err, norfResult) { if (!err) { console.log("Great Success!"); } else { console.error("Could not norf"); } }) } else console.error("Could not qux"); }); } else console.error("Could not baz"); }); } else console.error("Could not bar"); }); } else console.error("Could not foo"); });
Async Waterfall (not at all related to the development methodology)
async.waterfall([ function(cb) { foo(42, cb); }, bar, baz, qux, norf
], function(err, result) { if (!err) { console.log("Great Success!"); } else { console.error("Could not norf: " + err.message); } });
Better, but not perfect
A Promising Solution
foo(42) .then(bar) .then(baz) .then(qux) .then(norf) .then(function(norfResult) { console.log("Great Success!"); })
.catch(function(error) { console.error("Could not norf: " + err.message); });
Promises are like monads
User.find(42).then(function(user) { // returning a promise return user.getPosts(); }).then(function(posts) {
// posts is the resolved value });
User.find(42).then(function(user) { // returning a value return user.name; }).then(function(name) {
// name === user.name });
Functional.
User.find(42).then(function(user) { return user.getPosts(); }).filter(function(post) { return /Lorem Ipsum/.test(post.body); }).map(function(post)
{ return post.getComments(); }).reduce(function(total, comment) { return comment.getLikes() .then(function(likes) { return total + likes.length; }); }, 0);
Broken Promises...
User.find(42).then(function(user) { return user.getPosts(); }).then(function(posts) { // yay, I have
posts! // but where is my user? }).then(...); Bringing ‘user’ to the party
User.find(42).then(function(user) { return user.getPosts() .then(function(posts) { // yay, I have
posts! // and I have a user! )}; }).then(...); Promise Hell?
var user; User.find(42).then(function(_user_) { user = _user_; return user.getPosts() }).then(function(posts)
{ // yay, I have posts! // and I have a user! }).then(...); Klutzy variables?
var findUser = User.find(42); findUser.then(function(user) { return user.getPosts(); }).then(function(posts) {
var user = findUser.value(); // yay, I have posts! // and I have a user! }).then(...); ‘Resolved’ values?
var nizzleUserPosts = function(user) { return user.getPosts() .then(function(posts) { //
yay, I have posts! // and I have a user! }); } User.find(42).then(nizzleUserPosts) .then(...); Refactor that Shizz-Nizzle!
Regret?
None
Non-blocking means code sometimes runs off without you
The WTFs of Asynchronous-ness “I called this here and it
console.log’s there, wtf?” “Foo is happening before Bar, wtf?” “I called Bar, but it never happened, wtf?” “I never called Baz, but it’s happening, wtf?”
I’ve never missed ActiveRecord so much
Sequelize ORM
Migrations that needed to be migrated
Table “SequelizeMeta” has no column “to”
Associations that can’t associate
User.hasMany(Post); //... User.find(42, {include: Post}); //... Error: User and Post
not associated!
Source Maps while testing, anyone?
$ gulp test ... TypeError: evaluating ‘z[fn]’ /MyBlog/models/user.coffee:1:1 ... /MyBlog/models/user.coffee
1: ‘use strict’ 2: 3: module.exports = 4: foo: ->
This is not the require you’re looking for
Ruby: FooBar = require ‘foobar’ # Now you have FooBar
module # ... everywhere!
Node.js: FooBar = require(‘foobar’); // Now you have FooBar module
// ... in this file only
Circular dependency nightmares
require(‘foo’) in ‘bar’ require(‘bar’) in ‘foo’ you’re gonna have a
bad time
Sometimes I wish I could just `rails c`
Sometimes I wish I could just `binding.pry`
Acceptence
Express.js is fantastic
app.use(function(req, res, next) { // write some middlewarez next(); });
MIDDLEWARE ALL THE THINGS!
Authentication?
DB Connection?
Asset Pipeline?
`before` hook?
Middleware!
Node.js has come a long way
This ain’t yo mamma’s JavaScript
Walmart, PayPal, Ebay, Linkedin can’t be wrong, right?
Praised for its short development time
And IO performance (thanks to non-blocking)
ORMs and RDBMS support not quite there yet (IMO, don’t
quote me)
But huge NoSQL support (mongo, couch, etc)
Large, complex, enterprise-y software? maybe not
Microservices? Absolutely!
Thanks