AMD with RequireJS – Artur Dorochowicz – Module definition



AMD with RequireJS – Artur Dorochowicz – Module definition

1 0


presentation-amd-with-requirejs

Presentation: AMD with RequireJS

On Github ArturDorochowicz / presentation-amd-with-requirejs

AMD with RequireJS

Artur Dorochowicz

https://github.com/ArturDorochowicz/

Asynchronous Module Definition (AMD) API specifies a mechanism for defining modules such that the module and its dependencies can be asynchronously loaded.

https://github.com/amdjs/amdjs-api/wiki/AMD

RequireJS is a JavaScript file and module loader.

http://requirejs.org/

Module definition

// presentation.js
define(function () {
    return {
        title: 'My presentation',
        description: '...'
    };
});
Anonymous module. Modules are identified by a module id. Anonymous modules get the id based on the location of the files they are in. One-to-one mapping between modules and files. One module per file.

Module definition

// presentation.js
define({
    title: 'My presentation',
    description: '...'
});

Module definition

// presentation.js
define([], function () {
    return {
        title: 'My presentation',
        description: '...'
    };
});

Definition function with dependencies

// main.js
define(['jquery', 'presentation'], function ($, presentation) {
    $(document).ready(function () {
        $(document.body).text(presentation.title);
    });
});
Dependencies will be evaluated before the module. There is no ordering between dependencies (unless there are dependencies between them, direct or indirect). No globals (except for environment globals: window, document etc.)!

Definition function with dependencies

// main.js
define(function (require) {
    var $ = require('jquery');
    var presentation = require('presentation');

    $(document).ready(function () {
        $(document.body).text(presentation.title);
    });
});
Simplified CommonJS wrapper. Additionally improves readability and maintainability when there are many dependencies.

Named modules

// in jQuery since 1.7
define("jquery", [], function() {
    /* ... */
});

Running it

// main.js
require(
    ['jquery', 'knockout', 'PageViewModel'],
    function ($, ko, PageViewModel) {
        var vm = new PageViewModel();
        $(function () {
            ko.applyBindings(vm);
        });
    });
<html>
<head> <!-- ... --> </head>
<body>
    <!-- ... -->
    <script src="require.js" data-main="main"></script>
</body>
</html>
Technically, data-main causes a require() call, so main.js could contain a define() call. Doing require() there is a bit of a convention, also allows to alternatively simply include main.js with script tag.

Configuration

<html> <!-- ... -->
    <script>
    var require = {
        baseUrl: '/Scripts',
        waitSeconds: 60,
        urlArgs: 'cache_bust=' + (new Date()).getTime()
    };
    </script>
    <script src="require.js" data-main="app/main"></script>
<!-- ... --> </html>
// Scripts/app/main.js
require.config({
    paths: {
        'jquery': 'lib/jquery-2.1.0'
    }
});
require(['jquery', 'app/presentation'], function () { /* ... */ });
// Scripts/app/presentation.js
define( /* ... */ );
Default waitSeconds = 7.

Module configuration

require.config({
    config: {
        'app/presentation': {
            author: 'The Author'
        }
    }
});
// app/presentation.js
define(['module'], function (module) {
    var moduleConfig = module.config();
    var author = moduleConfig.author;
});

Non AMD scripts

require.config({
    paths: {
        'underscore': 'lib/underscore-1.5.2',
        'backbone': 'lib/backbone-1.1.0'
    },
    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        }
    }
});
define(['underscore'], function (_) { /* ... */ });

AMD with RequireJS

Artur Dorochowicz

https://github.com/ArturDorochowicz/presentation-amd-with-requirejs