Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Modern, Modular JavaScript Applications

Erik Grijzen
February 06, 2016

Building Modern, Modular JavaScript Applications

Presented @ Netcentric Summit 2016
Barceló convention center
Seville, Spain

More and more logic is moving from the server to the client side. The complexity of front-end applications is increasing rapidly and the end users are expecting highly interactive user interfaces.

Developing with a modular approach helps you to build more complex, scalable and robust applications. Existing modular solutions are very fragmented and are now being replaced by the new standards of ECMAScript 2015. We have new ways of writing our JavaScript code and this affects our current workflows.

Erik Grijzen

February 06, 2016
Tweet

More Decks by Erik Grijzen

Other Decks in Technology

Transcript

  1. Grouping code var myApp = window.myApp || {}; myApp.myModule =

    { init: function() { ... } }; myApp.myModule.init();
  2. var Counter = (function () { var counter = 0;

    function increment() { counter++; } return { increment: increment, }; })(); Counter.increment(); Exposing a public interface
  3. var Counter = (function () { var counter = 0;

    function increment() { counter++; } return { increment: increment, }; })(); Counter.increment(); Exposing a public interface Private implementation
  4. var Counter = (function () { var counter = 0;

    function increment() { counter++; } return { increment: increment, }; })(); Counter.increment(); Exposing a public interface Public interface Private implementation
  5. // counter.js var counter = 0; function increment(){ counter++; }

    module.exports = { increment: increment } CommonJS
  6. // counter.js var counter = 0; function increment(){ counter++; }

    module.exports = { increment: increment } CommonJS // main.js var counter = require("./counter.js"); counter.increment();
  7. // counter.js define('counter', function() { var counter = 0; function

    increment() { counter++; } return { increment: increment }; }); Asynchronous Module Definition (AMD)
  8. // counter.js define('counter', function() { var counter = 0; function

    increment() { counter++; } return { increment: increment }; }); Asynchronous Module Definition (AMD) // main.js define('main', ['counter'], function(counter) { counter.increment(); });
  9. (function (root, factory) { if (typeof define === 'function' &&

    define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.returnExports = factory(); } }(this, function () { var counter = 0; return { increment: function() { counter++; }; } })); Universal Module Definition (UMD)
  10. (function (root, factory) { if (typeof define === 'function' &&

    define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.returnExports = factory(); } }(this, function () { var counter = 0; return { increment: function() { counter++; }; } })); Universal Module Definition (UMD) AMD
  11. (function (root, factory) { if (typeof define === 'function' &&

    define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.returnExports = factory(); } }(this, function () { var counter = 0; return { increment: function() { counter++; }; } })); Universal Module Definition (UMD) AMD CJS
  12. (function (root, factory) { if (typeof define === 'function' &&

    define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.returnExports = factory(); } }(this, function () { var counter = 0; return { increment: function() { counter++; }; } })); Universal Module Definition (UMD) AMD CJS Global
  13. (function (root, factory) { if (typeof define === 'function' &&

    define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.returnExports = factory(); } }(this, function () { var counter = 0; return { increment: function() { counter++; }; } })); Universal Module Definition (UMD) AMD CJS Global Module
  14. // counter.js var counter = 0; function increment() { return

    counter++; } function reset() { counter = 0; } Multiple named exports
  15. // counter.js var counter = 0; export function increment() {

    return counter++; } export function reset() { counter = 0; } Multiple named exports
  16. // counter.js var counter = 0; export function increment() {

    return counter++; } export function reset() { counter = 0; } Named import // app.js import { increment } from 'counter'; increment(); // 1
  17. // counter.js var counter = 0; export function increment() {

    return counter++; } export function reset() { counter = 0; } Namespace import // app.js import * as counter from 'counter'; counter.increment(); // 1 counter.reset(); // 0
  18. // func.js export default function() { ··· } Default import

    // app.js import myFunc from 'func'; myFunc();
  19. Benefits over CJS and AMD? • Cleaner syntax • Sync

    and async • Multiple exports • Cyclic dependencies • Static module structure
  20. // Error if (someBooleanValue) { import myModule from 'module1'; }

    else { import myModule from 'module2'; } Static imports & exports
  21. In the future HTTP/2 will be able to load all

    modules asynchronously in production.
  22. Normal bundling behavior. import { increment } from ‘counter’; increment();

    counter.js main.js increment() { … } reset() { … }
  23. Normal bundling behavior. counter.js increment() { … } reset() {

    … } import { increment } from ‘counter’; increment(); main.js bundle.js increment() { … } reset() { … } increment();
  24. Removing unused exports. counter.js increment() { … } reset() {

    … } import { increment } from ‘counter’; increment(); main.js bundle.js increment() { … } reset() { … } increment();
  25. Removing unused exports. import { increment } from ‘counter’; increment();

    counter.js main.js bundle.js increment() { … } reset() { … } increment() { … } increment();
  26. { "name": "test-package", "version": "1.0.0", "main": "index.js", "repository": { "type":

    "git", "url": "git+https://github.com/..." }, "author": "Erik Grijzen" } package.json
  27. import styles from './component.css'; import template from './component.html'; import image

    from './logo.png'; var img = document.createElement('img'); img.src = image; Importing other assets