Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a Javascript module defined with AMD be extended?

First a bit of history, we have an engine which is made up of many javascript files which are essentially modules. These modules return a single class that are assigned to the global scope, although under a specified namespace.

The engine itself is used to display eLearning content, with each different eLearning course requiring slightly different needs, which is where we include javascript files into the page based on the necessary functionality. (There is only one entry page).

I've been trying to weigh up if it's worth changing to AMD, require.js and r.js or if it's better to stay with our current system which includes everything required on the page and minimises it into one script.

One of my biggest problems with going to AMD would be that it seems to be harder to extend a class easily. For example, sometimes we have to adjust the behaviour of the original class slightly. So we add another script include on the page that extends the original class by copying the original prototype, execute the original function that's being overridden with apply and then do whatever additional code is required.

Can you extend an AMD module without adapting the original file? Or am I missing the point and we're best staying with what we're doing at the moment?

like image 762
John_ Avatar asked Apr 25 '12 08:04

John_


People also ask

What does AMD stand for JavaScript?

Asynchronous module definition (AMD) is a specification for the programming language JavaScript. It defines an application programming interface (API) that defines code modules and their dependencies, and loads them asynchronously if desired.

How do you define a module in JavaScript?

A module in JavaScript is just a file containing related code. In JavaScript, we use the import and export keywords to share and receive functionalities respectively across different modules. The export keyword is used to make a variable, function, class or object accessible to other modules.

How does AMD work?

It allows a developer to place the module in a different path to give it a different ID/name. The AMD loader will give the module an ID based on how it is referenced by other scripts. However, tools that combine multiple modules together for performance need a way to give names to each module in the optimized file.

What is AMD script?

The Asynchronous Module Definition (AMD) format is the module format that Dojo adopted starting with Dojo 1.7. It provides many enhancements over the legacy Dojo module style, including fully asynchronous operation, true package portability, better dependency management, and improved debugging support.


1 Answers

I recently started a project using RequireJS, and the method I use to extend underscore boils down to something like this:

Relevant Directory Structure:

  • /scripts
  • /scripts/underscore.js
  • /scripts/base/underscore.js

The real underscore library goes to /scripts/base/underscore.js.

My extensions go in /scripts/underscore.js.

The code in /scripts/underscore.js looks like this:

define(['./base/underscore'], function (_) {
    'use strict';

    var exports = {};

    // add new underscore methods to exports

    _.mixin(exports); // underscore's method for adding methods to itself

    return _; // return the same object as returned from the underscore module
});

For a normal extension, it could look more like this:

define(['underscore', './base/SomeClass'], function (_, SomeClass) {
    'use strict';

    _.extend(SomeClass.prototype, {
        someMethod: function (someValue) {
            return this.somethingOrOther(someValue * 5);
        }
    });

    return SomeClass;
});

Note on underscore: Elsewhere I used the RequireJS shim-config to get underscore to load as an AMD module, but that should have no effect on this process with non-shimmed AMD modules.

like image 195
Keen Avatar answered Sep 20 '22 23:09

Keen