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

JavaScript module systems

JavaScript module systems

The idea of this presentation is to talk about the importance and aplicability of a module system on a programming language. I give examples and use cases of the current standards we have in the JavaScript world including a notable mention to Harmony modules.

Links:

Netshoes
http://netshoes.com.br

FEMUG-SP (Front-End Meetup Group São Paulo)
http://sp.femug.com

ZOFE podcast (Zone of Front-Enders)
http://zofe.com.br

Module Pattern
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

CommonJS spec
http://wiki.commonjs.org/wiki/CommonJS

CommonJS Modules spec
http://wiki.commonjs.org/wiki/Modules

Browserify
http://browserify.org

AMD
https://github.com/amdjs/amdjs-api/blob/master/AMD.md

Why AMD?
http://requirejs.org/docs/whyamd.html

RequireJS
http://requirejs.org

RequireJS plugins
http://requirejs.org/docs/plugins.html

RequireJS optimization tool
http://requirejs.org/docs/optimization.html

Harmony Modules
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-modules

Babel (previously called 6to5)
https://github.com/babel/babel

Traceur
https://github.com/google/traceur-compiler

Rafael Rinaldi

February 19, 2015
Tweet

More Decks by Rafael Rinaldi

Other Decks in Technology

Transcript

  1. Awesome because • You can implement whatever programming paradigm you

    want; • Easy to learn. Just create a bunch of functions and rock on! • Easy to run. The only requirement is a browser.
  2. Awkward because • It has lots of gotchas; • The

    browser environment itself is very complex and unpredictable; • The community is still evolving; there’s no “right way” of doing things; • “Toy language” legacy.
  3. // Go module system package log import ( "helpers/string/format", "fmt"

    ) func warn() { fmt.Println(format("Of course I have a module system!")) }
  4. Multiple script tags • Somewhat sane code organization; • Multiple

    file requests; • Relies on the order that scripts are defined; • Zero control over global name collision.
  5. var Module = (function () { // "private" var myPrivateVariable,

    myPrivateMethod; myPrivateVariable = 'foo'; myPrivateMethod = function() {} // "public" return { myPublicVariable: 'bar', myPublicMethod: function () {} }; })();
  6. Module Pattern • Provide a nice way of organizing modules

    and exposing their APIs; • Still doesn’t solve dependency organization nor dependency loading.
  7. CommonJS is a community effort to define best practices with

    a goal of compatibility across multiple environments
  8. // No `define()`, the file itself is a closure //

    Nice way to `require()` dependencies var log = require('debug/log'); var toArray = require('helpers/toArray'); var parseJSON = require('serialization/json').parse; function lorem() { log('I am a CommonJS module!'); } // Expose the public API exports.lorem = lorem; /* To use this module we've created, simple `require()` it: */ var Module = require('module'); // Calling a public method Module.lorem(); // I am a CommonJS module!
  9. CommonJS • The beauty of CommonJS is its simplicity; •

    Perfect for server side JS; • Synchronous nature, doesn’t know nothing about the browser; • Browserify kinda solves that by compiling modules to vanilla JS.
  10. AMD

  11. // Define a new module, the file name will be

    set as the id define( // Module dependencies ['debug/log', 'helpers/toArray', 'serialization/json/parse'], // Module implementation function(log, toArray, parseJSON) { function lorem() { log('I am an AMD module!'); } return { lorem: lorem } } );
  12. /* To use this module we've created, simply define it

    as a dependency and use it: */ // Creating a new module that uses our previously created module define(['module'], function(Module) { console.log(Module.lorem()); // I am an AMD module! });
  13. AMD • The syntax looks a bit weird at first

    glance (but you get used to it) • You can use whatever patterns and paradigms you want, AMD will just give you a sane module system to work with; • Easy way to spot module dependencies; • All dependencies are ready to be used on module implementation.
  14. The most popular module loader for AMD is by far

    RequireJS (but there are others)
  15. require.config({ // Base path for all the modules loaded baseUrl:

    'assets/js', paths: { // Path aliases are awesome 'foo': 'lib/lorem/ipsum/dolor/foo', // Super easy to implement things like cache busting 'bar/baz': 'bar/baz_v0.3.2' } });
  16. define( // Plugins always end with a bang `!` ['text!./tmplt/sliderTemplate.mustache',

    'image!./img/doge.png'], function(sliderTemplate, doge) { var template = sliderTemplate; document.body.appendChild(doge); } );
  17. define(['require'], function(require) { // List of files to be lazy

    loaded var files = ['vendors/analytics', 'vendors/ab_test']; // Calling it directly just so you can get the idea // But you could wait for a user interaction, for example require(files, function(analytics, ab_test) { analytics.initialize(); ab_test.initialize(); }); });
  18. AMD Goodies • No build step required; • Offers an

    optimisation tool called r.js that makes it really easy to generate file wrappers/bundles for production.
  19. // Regular import import 'file' from 'io/file'; // Import wildcard

    import * as helpers from 'helpers'; // Named imports import {sha2, md5} from 'crypto'; // Export a function export function warn(message) { console.warn(message); } // Export a constant export const pi = 3.14; // Default exports export default function() { console.log('I am the default module method!'); }
  20. // Native support for classes as well import MyClass from

    'MyClass'; let instance = new MyClass();
  21. Harmony modules • The way that ES6 loads and evaluates

    code is very similar to AMD’s approach; • ES6 final spec is already being implemented but it’s going to take some time to be well spread across all environments; • In the meantime you can start playing with it using a transpiler such as babel (previously called 6to5) or Traceur from Google; • Doesn’t really fit into production yet because it relies on a large vendor library and even a runtime to work properly.