Modularize your Javascript

with RequireJS

A. Matías Quezada (amatiasq)

History

Global variables

var myFramework = { ... };

IIFE (immediate invocation function expression)

(function(global) {
  // private content

  global.myFramework = { ... };
})(this);

CommonJS modules

From CommonJS - Used in NodeJS

Export

exports.greet = "hello";
module.exports = { greet: "hello" };

Import

var myModule = require('./my-module');
var greet = require('./my-module').greet;

CommonJS modules

Pros

Cons

Asyncronous Module Definition

Create module

define('./my-module', [], function() { ... });

Export

define('./my-module', [], function() {
  return "hello";
});

Import

define('./other-module', [ './my-module' ], function(myModule) {
  console.log(myModule);
});

AMD

Pros

Cons


RequireJS



An AMD implementation for browsers

Pros

Cons

Error messages

Configuration (docs)

Configuration (docs)

Example configuration

// requirejs-config.js
requirejs.config({

  baseUrl: 'js/',

  urlArgs: 'nocache=' + Date.now(),

  paths: {
    'underscore': '../bower_components/underscore/underscore',
    'moment': '../bower_components/moment/moment',
    'angular-core': '../bower_components/angular/angular',
    'angular-sanitize': '../bower_components/angular-sanitize/angular-sanitize',
    'angular': '../bower_components/angular-route/angular-route',
    'utils': '../vendor/utils/',
  },

  shim: {
    'underscore': { exports: '_' },
    'angular-sanitize': [ 'angular-core' ],
    'angular': {
      deps: [ 'angular-core', 'angular-sanitize' ],
      exports: 'angular',
    },
  },
})(['main']);

RequireJS' AMD mode

define([ 'underscore', './my-module', './utils' ],
  function(_, myModule, utils) {
    // code
});
define([
  'underscore',
  './my-module1',
  './my-module2',
  './my-module3',
  './my-module4',
  './utils'
], function(
  _,
  myModule1,
  myModule2,
  myModule3,
  myModule4,
  utils
) {
  // code
});

RequireJS' CommonJS mode

define(/* no deps */ function(require, exports, module) {
  'use strict';

  var _ = require('underscore');
  var myModule1 = require('./my-module1');
  var clone = require('./utils').clone;
  var myModule2 = require('./my-module2');
  var myModule3 = require('./my-module3');
  var myModule4 = require('./my-module4');

  exports.myValue = 1;

  module.exports = function() { ... };

  // non CommonJS
  return function() { ... };
});

Build process

$ npm install requirejs -g
$ r.js -o build-config.js
// build-config.js
({
  appDir: 'public',
  mainConfigFile: 'public/js/requirejs-config.js',
  name: 'main',
  insertRequire: [ 'main' ],
  out: 'public/build.js',
  optimize: 'none', // 'uglify' - 'uglify2' - 'closure'

  paths: {
    'angular-core': '../bower_components/angular/angular.min',
    'angular': '../bower_components/angular-route/angular-route.min',
    'angular-sanitize': '../bower_components/angular-sanitize/angular-sanitize.min',
  },
});

On HTML

<html>
  <head>...</head>
  <body>
    ...

    <!-- build:js build.js -->
    <script
      src="bower_components/requirejs/require.js"
      data-main="js/requirejs-config"></script>
  </body>
</html>

Plugins

define(function(require) {

  var template = require('text!../templates/my-template.html');

  var myModule = require('cs!./my-module');

  require('less!../styles/my-styles.less');

  require('domReady!');
});



And more things I know nothing about...

ECMAScript 6

// test.js
import _ from 'underscore';
import { pow, sqrt } from '@math';

export var sqrt2 = sqrt(2, 2);
export function foo() { };

AMD sugar syntax

System.register("test",
  ["underscore", "@math"], function(exports) {

  var _ = System.get("underscore").default;
  var { pow, sqrt } = System.get("@math");

  exports.sqrt2 = sqrt(2, 2);
  exports.foo = function foo() { };
});



THANKS




Questions?




Slides at https://github.com/amatiasq/requirejs-speech-amatiasq