Is it possible to use the default node require
function in a file that has been called through requirejs
?
define(["require", "exports"], function(require, exports) {
//...
var Schema = require(DaoPublic._schemasDirectory + schemaFilename);
}
I always get ReferenceError: module is not defined
, I also tried to load the schema using requireJs, same, because the file itself is coded as CommonJs, not AMD compatible.
Any solution?
Note that the loaded schema is in CommonJS and I need to keep this way, since it's used by several DAO, some in AMD and other in CommonJs. (Funny part)
Example of requested file (schema):
var userSchema = {
/**
* User Login, used as id to connect between all our platforms.
*/
login: {
type: String,
match: /^[a-zA-Z0-9_-]+$/,
trim: true,
required: true,
notEmpty: true,
unique: true,
check: {
minLength: 4,
maxLength: 16
}
}
};
module.exports = userSchema;
The problem is that your code is set so that RequireJS is able to find the CommonJS module by itself. However, when RequireJS is running in Node and cannot find a module, it will call Node's require
function, which is what you need. So it is possible (with RequireJS) to have an AMD module use Node's require
but the trick is getting RequireJS to not see the module in the first place.
Here's a proof of concept. The main file named test.js
:
var requirejs = require("requirejs");
function myRequire(path) {
if (path.lastIndexOf("schemas/", 0) === 0)
path = "./" + path;
return require(path);
}
requirejs.config({
paths: {
"schemas": "BOGUS"
},
nodeRequire: myRequire
});
requirejs(['foo'], function (foo) {
console.log(foo);
});
The file foo.js
:
define(["require", "exports"], function(require, exports) {
return require("./schemas/x") + " by way of foo";
});
The file schemas/x.js
:
module.exports = "x";
If you run it with node test.js
, you'll get on the console:
x by way of foo
I'm calling this a "proof of concept" because I've not considered all eventualities.
The paths
setting is there to throw RequireJS off track. BOGUS
must be a non-existent directory. When RequireJS tries to load the module ./schemas/x
, it tries to load the file ./BOGUS/x.js
and does not find it. So it calls Node's require
.
The nodeRequire
setting tells RequireJS that Node's require
function is myRequire
. This is a useful lie.
The myRequire
function changes the path to add the ./
at the start before calling Node's require. The issue here is that for some reason RequireJS transforms ./schemas/x
to schemas/x
before it gives the path to Node's require
function, and Node will then be unable to find the module. Adding back the ./
at the start of the path name fixes this. I've tried a whole bunch of path variants but none of them worked. Some variants were such that RequireJS was able to find the module by itself and thus never tried calling Node's require
or they prevented Node from finding the module. There may be a better way to fix this, which I've not found. (This is one reason why I'm calling this a "proof of concept".) Note that I've designed this function to only alter the paths that start with schemas/
.
I've looked at other possibilities but they did not appear to me very promising. For instance, customizing NODE_PATH
would eliminate myRequire
but such customization is not always doable or desirable.