Rix*_*Rix 3 javascript node.js
我正在尝试创建一个require包装器来加载依赖项,但我发现有一件事很难让它作为原始的require函数.当路径是相对路径时,包装器无法解析为正确的路径,因为我的加载器和调用者文件不在同一个文件夹中.这是一个简化的描述.
index.js
lib/
loader.js
foo/
bar.js
baz.js
Run Code Online (Sandbox Code Playgroud)
index.js
var loader = require('./lib/loader.js'),
bar = require('./foo/bar.js');
bar(loader);
Run Code Online (Sandbox Code Playgroud)
LIB/loader.js
module.exports = function (path) {
return require(path);
};
Run Code Online (Sandbox Code Playgroud)
富/ bar.js
module.exports = function(loader) {
var baz = loader('./baz.js');
console.log(baz);
};
Run Code Online (Sandbox Code Playgroud)
富/ baz.js
module.exports = 'baz';
Run Code Online (Sandbox Code Playgroud)
显然,当执行index.js时,找不到baz.js文件.有没有办法解决到正确的文件?
我找到了一个相对的解决方案,但它没有用.
您可以使用从另一个模块的上下文module.require调用require,因此您可以通过将该上下文传递给loader方法来完成此操作:
LIB/loader.js
module.exports = function (moduleContext, path) {
return moduleContext.require(path);
};
Run Code Online (Sandbox Code Playgroud)
富/ bar.js
module.exports = function(loader) {
var baz = loader(module, './baz.js');
console.log(baz);
}
Run Code Online (Sandbox Code Playgroud)
我同意@JohnnyHK 的观点,即传递上下文module是一个很酷的解决方案,但我仍然希望保持调用简单。最后我明白了我提到的答案,我得到了我想要的。
加载器.js
var getCaller, path;
path = require('path');
getCaller = function() {
var stack, traceFn;
traceFn = Error.prepareStackTrace;
Error.prepareStackTrace = function(err, stack) {
return stack;
};
stack = (new Error()).stack;
Error.prepareStackTrace = traceFn;
return stack[2].getFileName();
};
module.exports = function(file) {
var base;
base = path.dirname(getCaller());
return require(path.resolve(base, file));
};
Run Code Online (Sandbox Code Playgroud)
该getCaller函数使用错误跟踪堆栈来获取其调用者的调用者的文件名。我知道这是一种非常棘手的方法,并且我不推荐将其作为通用解决方案,因为它与不同版本的 Node.js 的兼容性尚未经过测试。
该加载器用于准备依赖项,因此不需要迭代node_modules文件夹。唯一的两种情况是相对路径和绝对路径,它们都可以被这个加载器正确处理。