Wrap Require In Node.js Which Can Resolve Relative Path Call
Solution 1:
You can use module.require
to call require
from another module's context, so you could do this by passing that context into the loader
method:
lib/loader.js
module.exports = function(moduleContext, path) {
return moduleContext.require(path);
};
foo/bar.js
module.exports = function(loader) {
var baz = loader(module, './baz.js');
console.log(baz);
}
Solution 2:
I agree with @JohnnyHK that passing the module
context is a cool solution, but I still want to keep the calls simple. Finally I understand the answer I mentioned, and I get what I want.
loader.js
var getCaller, path;
path = require('path');
getCaller = function() {
var stack, traceFn;
traceFn = Error.prepareStackTrace;
Error.prepareStackTrace = function(err, stack) {
return stack;
};
stack = (newError()).stack;
Error.prepareStackTrace = traceFn;
return stack[2].getFileName();
};
module.exports = function(file) {
var base;
base = path.dirname(getCaller());
returnrequire(path.resolve(base, file));
};
The getCaller
function use error trace stack to get the filename of the caller of it's caller. I know it's a very tricky approach, and I don't recommend it as a common solution since its compatibility to different versions of Node.js has not been tested.
Note
This loader is used for preparing dependencies, so it doesn't need to iterate node_modules folders. The only two cases are relative path and absolute path, and they can all be correctly processed by this loader.
Solution 3:
Using __dirname
__dirname
may be what you need here. You can use it to turn a relative path into an absolute path which will work with require
.
var resolve = require('path').resolve;
var relativePathToModule = './a/b/c';
// resolve is not strictly necessary, but it does clean up the path for you.var absolutePathToModule = resolve(__dirname + relativePathToModule);
You can pass absolutePathToModule
to a require in any module and it will always find the right module.
Note that __dirname
is the absolute path to the directory of the module in which it is used.
Using require.resolve
Alternatively, you can use the require
machinery itself to resolve the module for you:
var relativePathToModule = './a/b/c';
var absolutePathToModule = require.resolve(relativePathToModule);
This has the benefit of throwing when no module can be resolved, and omitting the __dirname
.
Note
These don't quite do what you want, but are close to the way require
resolves paths. Both require
and __dirname
belong to the module they are used in, so anything else will mean passing the context of a module around to use the above machinery in another module (see JohnnyHK's answer).
Post a Comment for "Wrap Require In Node.js Which Can Resolve Relative Path Call"