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
The Modern JavaScript Application
Search
Andy Appleton
October 16, 2012
Technology
710
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
The Modern JavaScript Application
A talk at FOWA London
Andy Appleton
October 16, 2012
More Decks by Andy Appleton
See All by Andy Appleton
Done is better than perfect
appltn
0
610
Rage against the state machine
appltn
1
600
Modular UI with (Angular || Ember)
appltn
0
150
Building web apps with Express
appltn
4
530
Object Creation Pattern Performance
appltn
1
840
Introducing Mint Source
appltn
1
420
Other Decks in Technology
See All in Technology
AI ネイティブな組織に Gemini Enterprise Agent Platform がなぜ必要なのか
asei
1
190
JavaScript 研修 (2026)
recruitengineers
PRO
2
470
【CEDEC2026】『Relink』を拡張せよ - 『GRANBLUE FANTASY: Relink - Endless Ragnarok』の開発速度と品質を守るCI運用
cygames
PRO
0
140
Invisible to AI? Making TYPO3 Sites Quotable by AI Search Systems
wolfgangwagner
0
170
生成 AI の基礎 〜 サンプル実装で学ぶ基本原理
enakai00
7
4.4k
モダンフロントエンド 開発研修
recruitengineers
PRO
4
570
もう一度考える SRE チームの作り方・育て方 / Rethinking SRE #1: Building and Growing SRE Teams
rrreeeyyy
6
1k
Webアクセシビリティ入門 2026
recruitengineers
PRO
3
460
AI駆動開発は個人技からチーム戦へ:組織でAIを使いこなすための実践設計
moongift
PRO
0
480
MIRU 2026 チュートリアル
keisuke198619
0
870
Goでデータパイプラインを作ろう
sansantech
PRO
1
360
オートロックマンションなのに、各部屋は施錠なし!? 攻撃者が組織内ネットワークで大暴れする理由 / The Front Door Is Locked, but the Rooms Are Wide Open: Why Attackers Move Freely Inside Enterprise Networks
nttcom
1
1.6k
Featured
See All Featured
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
450
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
990
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
230
Bash Introduction
62gerente
615
220k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
210
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
890
Ruling the World: When Life Gets Gamed
codingconduct
0
290
Faster Mobile Websites
deanohume
310
32k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Transcript
The Modern JavaScript Application Andy Appleton @appltn http://appleton.me
JS is growing up we are doing more and more
with it and we need more robust tools
$(function(){ $('.thing').on('click', function(ev){ ev.preventDefault(); var $link = $(this) $.get($link.attr('href'), function(data)
{ $link.fadeOut(function(){ $('body').append(data); }); }); }); });
We can do better other languages have rich sets of
tools and patterns, we can too!
None
None
None
Models var Person = Backbone.Model.extend({ sayName: function(){ return this.get('name'); }
}); var andy = new Person({ name: 'Andy' }); andy.sayName(); // => 'Andy'
Collections var People = Backbone.Collection.extend({ sayNames: function(){ return this.map(function(model){ return
model.get('name'); }).join(', '); } });
Views var PersonView = Backbone.view.extend({ render: function(){ this.el.innerHTML = this.model.get('name');
} });
Tools
None
None
Modules defined chunks of code which list their own dependencies
Our Model From Earlier define(['path/to/dependency'], function(dependency){ return Backbone.Model.extend({ // Adding
methods and properties }); });
Alternative Syntax define(function(require){ var dependency = require('path/to/dep'); return Backbone.Model.extend({ //
Adding methods and properties }); });
Structure & Conventions Split each module into a separate file
None
The Requests!
The Requests! The Humanity!
r.js The RequireJS build tool
$ node r.js -o config.js Concatenate & minify JS into
a single file Concatenate & minify CSS via @import
None
Templating
None
http://handlebarsjs.com/
var input = '<h1>{{ name }}</h1>'; var templateFn = Handlebars.compile(input);
var output = templateFn({ name: 'Andy' }); // => '<h1>Andy</h1>'
var input = ' <article>\ <header>\ <h1>{{title}}</h1>\ by {{author}} on
{{date}}\ </header>\ {{content}}\ </article>\ ';
index.html <script type="text/template" id="tpl-name"> <article> <header> <h1>{{title}}</h1> ...etc </script> my-view.js
var input = $('#tpl-name').text(); // ...compile etc
https://github.com/SlexAxton/require-handlebars-plugin
my-view.js define(function(require){ var templateFn = require('hbs!path/to/tpl'); // View now has
access to compiled template // function }); post-template.hbs <article> <header> <h1>{{title}}</h1> ...etc
my-view.js define(function(require){ var templateFn = require('hbs!path/to/tpl'); // View now has
access to compiled template // function }); post-template.hbs <article> <header> <h1>{{title}}</h1> ...etc
Handy Patterns
Mediator A central object to publish and subscribe to global
events
var mediator = _.clone(Backbone.Events); mediator.on('eventname', function(args){ console.log(args); }); mediator.trigger('eventname', 'sausages');
// => 'sausages' mediator.off('eventname');
Model Caching sharing model instances across views
define(function(require){ var _cache = {}, Model = Backbone.Model.extend(); Model.create =
function(opts) { if (opts.id && !_cache[opts.id]) { _cache[opts.id] = new Model(opts); } return _cache[opts.id]; }; return Model; });
define(function(require){ var _cache = {}, Model = Backbone.Model.extend(); Model.create =
function(opts) { if (opts.id && !_cache[opts.id]) { _cache[opts.id] = new Model(opts); } return _cache[opts.id]; }; return Model; });
define(function(require){ var _cache = {}, Model = Backbone.Model.extend(); Model.create =
function(opts) { if (opts.id && !_cache[opts.id]) { _cache[opts.id] = new Model(opts); } return _cache[opts.id]; }; return Model; });
Unit Testing
None
http://pivotal.github.com/jasmine/
var Person = Backbone.Model.extend({ sayName: function(){ return this.get('name'); } });
Our Model From Earlier (again)
describe('Person model', function(){ describe('#sayName', function(){ it('returns `name` attribute', function(){ var
person = new Person({ name: 'Andy' }); expect(person.sayName()).toEqual('Andy'); }); }); });
None
Automation
Grunt JS command line build tool http://gruntjs.com/
None
+ http://phantomjs.org/
None
None
None
https://github.com/mrappleton/jasmine-examples
None
Andy Appleton @appltn http://appleton.me