chris
chris

Reputation: 754

RequireJS - When specify module id in define()

In RequireJS documents (http://requirejs.org/docs/api.html#modulename), I couldn't understand this sentence.

You can explicitly name modules yourself, but it makes the modules less portable

My question is

  1. Why explicitly naming module makes less portable?
  2. When explicitly naming module needed?

Upvotes: 4

Views: 1845

Answers (2)

Louis
Louis

Reputation: 151511

Why explicitly naming module makes less portable?

If you do not give the module a name explicitly, RequireJS is free to name it whichever way it wants, which gives you more freedom regarding the name you can use to refer to the module. Let's say you have a module the file bar.js. You could give RequireJS this path:

paths: {
    "foo": "bar"
}

And you could load the module under the name "foo". If you had given a name to the module in the define call, then you'd be forced to use that name. An excellent example of this problem is with jQuery. It so happens that the jQuery developers have decided (for no good reason I can discern) to hardcode the module name "jquery" in the code of jQuery. Once in a while someone comes on SO complaining that their code won't work and their paths has this:

paths: {
    jQuery: "path/to/jquery"
}

This does not work because of the hardcoded name. The paths configuration has to use the name "jquery", all lower case. (A map configuration can be used to map "jquery" to "jQuery".)

When explicitly naming module needed?

It is needed when there is no other way to name the module. A good example is r.js when it concatenates multiple modules together into one file. If the modules were not named during concatenation, there would be no way to refer to them. So r.js adds explicit names to all the modules it concatenates (unless you tell it not to do it or unless the module is already named).

Sometimes I use explicit naming for what I call "glue" or "utility" modules. For instance, suppose that jQuery is already loaded through a script element before RequireJS but I also want my RequireJS modules to be able to require the module jquery to access jQuery rather than rely on the global $. If I ever want to run my code in a context where there is no global jQuery to get, then I don't have to modify it for this situation. I might have a main file like this:

define('jquery', function () {
    return $;
});

require.config({ ... });

The jquery module is there only to satisfy modules that need jQuery. There's nothing gained by putting it into a separate file, and to be referred to properly, it has to be named explicitly.

Upvotes: 4

iH8
iH8

Reputation: 28688

Here's why named modules are less portable, from Sitepen's "AMD, The Definite Source":

AMD is also “anonymous”, meaning that the module does not have to hard-code any references to its own path, the module name relies solely on its file name and directory path, greatly easing any refactoring efforts.

http://www.sitepen.com/blog/2012/06/25/amd-the-definitive-source/

And from Addy Osmani's "Writing modular javascript":

When working with anonymous modules, the idea of a module's identity is DRY, making it trivial to avoid duplication of filenames and code. Because the code is more portable, it can be easily moved to other locations (or around the file-system) without needing to alter the code itself or change its ID. The module_id is equivalent to folder paths in simple packages and when not used in packages. Developers can also run the same code on multiple environments just by using an AMD optimizer that works with a CommonJS environment such as r.js.

http://addyosmani.com/writing-modular-js/

Why one would need a explicitly named module, again from Addy Osmani's "Writing modular javascript":

The module_id is an optional argument which is typically only required when non-AMD concatenation tools are being used (there may be some other edge cases where it's useful too).

Upvotes: 1

Related Questions