CommonJS中的自定义`require`方法(特别是Node)

时间:2011-07-11 17:06:17

标签: javascript node.js commonjs

是否可以在一个模块中定义可以在另一个模块中调用的自定义require方法?

例如,在x / x.js

exports.xrequire = function(path) {
   console.log("requiring " + path);
   require(path);
};

在y / hello.js

console.log("Hello, world!");

然后在y / y.js

var xrequire = require("../x/x.js").xrequire;
xrequire("hello.js");

运行y.js时,应打印“Hello World”。

我知道这似乎是一个坏主意,但我确实有合理的理由去做。 ;)


此代码的问题是它尝试加载x / hello.js,而不是y / hello.js - 我希望它的工作方式与标准要求相同。

2 个答案:

答案 0 :(得分:1)

你当然可以这样做。它会成功避免在运行时修改pose problems的全局require.paths数组,并且不应该在将来的版本中出现问题。

您应该只需将简单require的模型设置到当前应用中即可。根据您的示例 x.js 应该包含。

var relative = 'y/';
exports.xrequire = function(path) {
   console.log("requiring " + relative + path);
   return require(relative+path);
};

然后,您就可以成功使用自定义require

var xrequire = require('x.js'),
    hello = xrequire('hello.js');

我不建议这样做,但如果你想真的偷偷摸摸,你可以覆盖require功能。

var require = xrequire;

如果您计划require,我肯定会在您的模块中详细记录这个:D这个功能,但它确实有效。

修改

如果文件不存在,您可以测试文件并回退到require

var relative = 'y/';
exports.xrequire = function(path) {
   var ret;
   try{
     ret = require(relative+path);
     console.log("requiring " + relative + path);
   }catch(e){
     console.log("requiring " + path);
     ret = require(path);
   }
   return ret;
};

我认为您可以尝试将process.cwd添加到require路径的开头,以强制首先查找正确的目录。老实说,这会让大多数开发人员感到困惑。我建议只为您的应用程序定义一个命名空间,并创建一个特殊的require函数,只检索那些命名空间的应用程序特殊函数。

答案 1 :(得分:0)

CommonJs模块规范要求将require命名为require,并使用字符串文字进行调用,以允许构建工具预加载模块。

特定的实现可能允许您执行您想要的操作,但在其他实现或升级时可能会失败。

编辑:上面的内容来自于我在学习commonJS模块时的回忆 - 它似乎没有在规范中以这种方式定义。