Francisco Goldenstein
Francisco Goldenstein

Reputation: 13767

RequireJS - define function is not returning dependencies correctly

I'm using RequireJS and when I define a new module using the function "define" I see the dependencies were resolved but the objects are not the modules I defined.

All the modules are defined in AMD format, setting a name, array of dependencies and a function. The exportation is done by return an object.

The dependencies resolved by "define" have these properties: exports, id, packaged, and uri. If I then call require function the dependencies are set correctly.

UPDATE: I created a test example with the described issue

HTML:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Test</title>
    <script src="/Scripts/require.js" data-main="../Scripts/main"></script>
    <script src="/Scripts/module.js"></script>
</head>
<body>
    <div> 
    </div>
</body>
</html>

main.js:

require(["module"], function (module) {
    module.test();
});

module.js:

define([], function () {

    function test() {
        return "a";
    }

    return {
        test: test
    };
});

Console: Uncaught TypeError: module.test is not a function

This happens because module is not resolved to the real module but to an object with properties:

-config { arguments: null, caller: null, length: 0, name: "config" }

-exports { id: "@r5", uri: "../Scripts/@r5.js" }

Setting a module name in the define function has the same result.

NOTE: in the example there was an issue detected by @Louis. A module cannot be named "module". This helped me fixed the example but didn't fix my real issue. Below I describe the solution.

SOLUTION:

My issue was related to a library called Ace (HTML editor). This is the link that helped me solve it: https://github.com/josdejong/jsoneditor/issues/173

Upvotes: 3

Views: 1564

Answers (2)

dbf
dbf

Reputation: 3453

Ok, so after reading

properties: exports, id, packaged, and uri.

I'm guessing, like @Louis said we would, that the example in the OP's question is not the example in the OP's (test-)project.

When defining a module, there are 2 (and lots of more) general ways of doing so.

On of them is explained in the docs titled CommonJS.

If a module is defined with

define(function(require, exports, module) {

   console.log(module);

});

then the 3rd argument module will indeed contain exports, id and uri as in.

{
   config: function config()
   exports: Object {  }
   id: "js/modules/handgrip/index.js?bust=1512509846564"
   uri: "js/modules/handgrip/index.js?bust=1512509846564&bust=1512509846564"
}

In order to "return" your module in the given context, you can export it with

define(function(require, exports, module) {

   // require a depedency already loaded in context
   var someDep = require('someDep1');

   module.exports = {
      // whatever this module is about ..
   }
});

Only if you define the module with a name, followed by dependencies, as in

define('thename', [ 'someDep1', 'seomDep2', 'etc..' ], function(dep1, dep2, ..) {

   // the arguments in this context are those listed in order as defined in the array (parameters)

}

you get your expected results ..

-- update after edit

Was in a Scrum-meeting, sorry ;) So it's quite clear, as @Louis wrote.

module, exports and require are reserved words.

The following have the same results

define(['require', 'exports', 'module'], function(require, exports, module) {
  console.log(module);
});

define(function(require, exports, module) {
  console.log(module);
});

Upvotes: 1

Louis
Louis

Reputation: 151370

With the edit you made, it is now possible to diagnose the issue. Do not name any module you write with the name module, and the problem will go away.

The name module is one of three reserved module names: module, require and exports. You should never name any of your own modules with these names.

When you ask RequireJS to load module, it is not loading your module. Instead, it simply returns an internal structure which is meant to provide information about the current module. It has fields like id, which gives the current module id (i.e. the module name) and url which gives the URL from which the module was loaded, and so on and so forth.

Upvotes: 3

Related Questions