在另一个模块的上下文中评估模块

时间:2011-07-14 22:16:12

标签: javascript node.js

我知道这非常非节点/ CommonJS-y原谅我。 (我正在编写各种类型的库,我希望我的库require方法在浏览器和NodeJS上完全相同。)

我想要做的是在当前模块的上下文中评估脚本 - 也就是说,如果我在模块中说exports.a = "100";,我想要{{1}在exports.a之后的"100"模块中的所有代码中等于require

如果不清楚,我很乐意详细说明。

2 个答案:

答案 0 :(得分:1)

这不是一个完整的答案,但希望能帮助你找到正确的方向。

过去几天我一直在搞乱Node创建模块的系统。基本上我想创建一些在全新的上下文和变量范围内调用的模块,为此我将定义一个有限的子集和Node的功能扩展。

我最终学习their source here,并特别关注NativeModule构造函数及其方法。

你会注意到模块的源代码是从一个文件中读取的,包含在一个代表一个函数的字符串中,并被评估为实际的代码。

包装器:

NativeModule.wrapper = [
   '(function (exports, require, module, __filename, __dirname, define) { ',
   '\n});'
];

调用该函数,该函数调用包含的模块代码。

从包装器中可以看到该函数需要六个参数,第一个参数是exports对象(从空开始)。它也传递了require函数,这就是为什么你可以访问require作为变量,即使require不是全局的。

模块代码填充exports对象,然后缓存exports,以便将来不需要完成所有工作。因此,当调用require( 'someModule' )时,它只查找缓存的exports对象并返回它。

我确信您可以在代码中执行类似的操作,只要您可以获取要需要的模块的源代码即可。

也许SomeModule.toString()对您来说已经足够了。不确定浏览器支持的一致性。


还有一个私有API,用于为模块设置环境。

process.binding('evals').Script

/*
{ [Function: Script]
  createContext: [Function],
  runInContext: [Function],
  runInThisContext: [Function],
  runInNewContext: [Function] }
*/

我最终需要使用createContextrunInContext让事情有效,但我猜你可能不会需要这样的事情。

答案 1 :(得分:0)

  

(我正在写一个各种类型的库,我想要我的库需要   在浏览器和NodeJS上完全相同的方法

如果我理解正确(如果没有,请原谅我;))你正在寻找像node-browserify这样的东西。

  

Browserify浏览器端require()用于节点模块和npm   封装

     

只需在browserify上指向一两个javascript文件即可   AST以递归方式读取所有require()。得到的捆绑包有   您需要的一切,包括拉入您可能拥有的库   使用npm安装!