I am trying to write some JS modules which should be usable in both a browser and node.js environment.
To facilitate this I'm writing these modules as AMD modules, and using requirejs in the Node.js environment to provide the define() function as well as the ability to load these modules.
However, I've encountered some behavior I do not understand.
I made a SSCCE that illustrates the problem:
├── bar.js
├── node_modules
│ └── foo
│ ├── foo.js
│ ├── index.js
│ ├── node_modules
│ │ └── requirejs
│ │ ├── bin
│ │ │ └── r.js
│ │ ├── package.json
│ │ ├── README.md
│ │ └── require.js
│ └── package.json
└── test.js
foo is a node module which wraps the AMD module foo.js
node_modules/foo/foo.js
define([], function() {
return function() {
console.log("This is foo!");
};
});
node_modules/foo/index.js
var requirejs = require('requirejs');
requirejs.config({
baseUrl: __dirname,
nodeRequire: require
});
module.exports = requirejs('foo');
bar.js is another AMD module:
define([], function() {
return function() {
console.log("This is bar!");
};
});
test.js is a script that wants to use both foo and bar:
var requirejs=require('requirejs');
requirejs.config(
{
baseUrl: __dirname,
nodeRequire: require
}
);
var foo=require("foo");
foo();
var bar=requirejs("bar");
console.log("bar is:",bar);
If I run test.js, I get this:
This is foo!
bar is: undefined
/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:393
throw err;
^
Error: Mismatched anonymous define() module: function () {
return function() {
console.log("This is bar!");
};
}
http://requirejs.org/docs/errors.html#mismatch
at makeError (/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:418:17)
at intakeDefines (/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:1501:36)
at null._onTimeout (/home/harmic/tmp/test_rjs/node_modules/foo/node_modules/requirejs/bin/r.js:1699:25)
at Timer.listOnTimeout (timers.js:119:15)
There are two things that don't make sense to me here.
In test.js, the call to
requirejs("bar")returns undef. In fact it appears that the loading of the module is deferred, as if there were some circular dependancy going on, because it is only after it has returned that the module definition for bar is being executed.Why does it think this is an anonymous
define()? My use case does not appear to meet the criteria in the given URL.
To supress the second issue I tried naming the define in bar.js, like this:
define('bar', [], function() {
...
That works in the sense that the exception is gone, but requirejs("bar") still
returns undef.
The example is a simplified version of what I am trying to do - basically I will have a number of modules, which will contain some common components that can be used in browser and in node, and some node specific components that will only be used in node. There will be dependancies between the modules.
If there is some better way of doing this then I'm open to that also.
requirejs("foo"). This is pretty much a requirement when wrapping AMD modules for use in Node, since Noderequire()is synchronous. - harmicbar.jslocated relative to your other files? - Louis