Successfully reported this slideshow.

JSConf US 2014: Building Isomorphic Apps

8

Share

Loading in …3
×
1 of 71
1 of 71

JSConf US 2014: Building Isomorphic Apps

8

Share

Download to read offline

Slides from Spike Brehm's talk at JSConf US 2014. Topics include the etymology of "Isomorphic JavaScript", examples is isomorphic apps in the wild, reasons behind the growing trend towards isomorphic apps, and how to build an isomorphic module using Browserify & NPM.

Slides from Spike Brehm's talk at JSConf US 2014. Topics include the etymology of "Isomorphic JavaScript", examples is isomorphic apps in the wild, reasons behind the growing trend towards isomorphic apps, and how to build an isomorphic module using Browserify & NPM.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

JSConf US 2014: Building Isomorphic Apps

  1. 1. Building Isomorphic Apps Spike Brehm @spikebrehm
  2. 2. @spikebrehm @AirbnbNerds Spike Brehm
  3. 3. Isomorphic JavaScript.
  4. 4. WTF is Isomorphic JavaScript?
  5. 5. JavaScript code that can be shared between environments.
  6. 6. JavaScript code that can be shared between environments.
  7. 7. JavaScript code that can be shared between environments.
  8. 8. JavaScript code that can be shared between environments.
  9. 9. Backend Ruby Python Java PHP Node.js Persistence Client JavaScript Shared JavaScript DOM manipulation UX View layer Application logic Routing
  10. 10. Etymology of “Isomorphic JavaScript”.
  11. 11. adjective corresponding or similar in form and relations. i·so·mor·phic
  12. 12. i·so·mor·phic formsame
  13. 13. http://blog.nodejitsu.com/scaling-isomorphic-javascript-code/
  14. 14. “monomorphic” “heteromorphic” “homomorphic” “polymorphic” You’re using it wrong!
  15. 15. Isomorphic JavaScript in the wild.
  16. 16. Flickr
  17. 17. Flickr
  18. 18. ! Yahoo’s Modown libraries (successor to Mojito). Flickr
  19. 19. Instagram*
  20. 20. Instagram*
  21. 21. ! Facebook’s React library in a Django app. Instagram*
  22. 22. Airbnb Mobile
  23. 23. Airbnb Mobile
  24. 24. ! Airbnb’s Rendr library, built on Backbone and Express. Airbnb Mobile
  25. 25. Asana
  26. 26. ! Entire App runtime synced between client & server. Asana
  27. 27. Meteor
  28. 28. ! Realtime app framework. Meteor
  29. 29. Wy go to the trouble?
  30. 30. Initial pageload speed. Performance Crawlable single-page apps. SEO* Reduce code duplication. Maintainability Run code anywhere. Flexibility
  31. 31. Isomorphic use cases.
  32. 32. • Templating • I18n • Date & currency formatting • Application logic • Routing • Model validation • API interaction • ...? Isomorphic use cases.
  33. 33. Isomorphic JavaScript is a spectrum.
  34. 34. Entire view layer and app logic shared Small bits of view layer or logic shared
  35. 35. Many abstractions Few abstractions
  36. 36. View layer shared Entire app runtime synced between client & server
  37. 37. Isomorphic JavaScript can be or shimmed per environment . environment- agnostic
  38. 38. Does not depend on browser-specific properties (window) or server-specific properties (process.env, req.cookies). Environment-agnostic
  39. 39. Example: Handlebars.js var template = ! '<ul>' ! '{{#each posts}}' ! ' <li>{{title}}</li>' ! '{{/each}}' ! '</ul>'! ;!  ! var templateFn = Handlebars.compile(template)! , html = templateFn({posts: posts});
  40. 40. Provide shims for accessing environment-specific properties so module can expose a single API. window.location.pathname vs. req.path Shimmed per environment
  41. 41. Example: Superagent superagent! .get('/api/posts.json')! .end(function(res) {! if (res.status === 200) {! console.log("Posts:", res.body);! } else {! console.error("Error");! }! });
  42. 42. Abstractions.
  43. 43. Abstraction: User Agent Client navigator.userAgent Server req.get('user-agent')
  44. 44. Abstraction: Cookies Client document.cookie =! 'myCookie=1; Domain=.example.org'; Server res.setHeader(! 'Set-Cookie: myCookie=1; ' +! 'Domain=.example.org'! );
  45. 45. Abstraction: Redirects Client document.location.href = '/login';! ! window.pushState({}, '', '/login'); Server res.redirect('/login');
  46. 46. How to isomorph.
  47. 47. Let’s write a module that abstracts the setting of cookies, providing the same API for client & server.
  48. 48. setCookie('myCookie', 'the value');
  49. 49. setCookie('myCookie', 'the value'); document.cookie = 'myCookie=the%20value'; or res.setHeader('Set-Cookie: myCookie=the%20value;');
  50. 50. setCookie('myCookie', 'the value', {! path: '/',! domain: '.example.org',! expires: new Date(2014, 12, 31)! }); document.cookie =! 'myCookie=the%20value; Domain=.example.org; ' +! 'Path=/; Expires=Sat, 31 Jan 2015 05:00:00 GMT';
  51. 51. Eww, that looks hard.
  52. 52. NPM & Browserify to the rescue.
  53. 53. Browserify Use CommonJS to require() modules in the browser.
  54. 54. Browserify Package dependencies from node_modules into our bundle.
  55. 55. How do we make a shimmed-per- environment module? Utilize package.json “browser” field.
  56. 56. {! "name": "set-cookie",! "dependencies": {...}! }! ! ! !
  57. 57. {! "name": "set-cookie",! "dependencies": {...},! "browser": "./lib/client.js"! }! ! ! Swap out the entire implementation.
  58. 58. {! "name": "set-cookie",! "dependencies": {...},! "browser": {! "./lib/node.js": "./lib/client.js"! }! }! Swap out specific files.
  59. 59. {! "name": "set-cookie",! "dependencies": {...},! "browser": {! "./lib/node.js": "./lib/client.js",! "cookie": "cookie-browser"! }! } Swap out dependencies.
  60. 60. Let’s build `set-cookie`. https://github.com/spikebrehm/set-cookie
  61. 61. Module structure .! "## index.js! "## lib! $   %## setter! $   "## index.js! $   %## client.js! "## node_modules! $   %## cookie
  62. 62. // ./index.js! ! var cookie = require('cookie');! var setter = require('./lib/setter');! ! module.exports = function(name, value, options) {!   var cookieStr = cookie.serialize(name, value, options);!   setter(cookieStr, options);! };
  63. 63. // ./lib/setter/index.js! ! module.exports = function setter(cookieStr, options) {!   var res = options && options.res;! !   if (!res)! throw new Error('Must specify `res` ' +! 'when setting cookie.’);! !   res.setHeader('Set-Cookie', cookieStr);! };
  64. 64. // ./lib/setter/client.js! ! module.exports = function setter(cookieStr) {!   document.cookie = cookieStr;! };
  65. 65. // ./package.json! ! {! "name": "set-cookie",! "dependencies": {! "cookie": "^0.1.2"! },! "browser": {! "./lib/setter/index.js": "./lib/setter/client.js"! }! }
  66. 66. // ./index.js! ! var cookie = require('cookie');! var setter = require('./lib/setter');! ! module.exports = function(name, value, options) {!   var cookieStr = cookie.serialize(name, value, options);!   setter(cookieStr, options);! };
  67. 67. How to isomorph in a nutshell.
  68. 68. @spikebrehm @AirbnbNerds Thanks! More resources available at http://spike.technology
  69. 69. @spikebrehm @AirbnbNerds Thanks! More resources available at http://spike.technology We’re hiring!!!We’re hiring!!!We’re hiring!!!We’re hiring!!!We’re hiring!!!We’re hiring!!!

×