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

JavaScript module systems

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

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

Avatar for Rafael Rinaldi

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.