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

我知道这是非常节点/ CommonJS-Y-原谅我。 (我正在编写一个类库,我希望我的库的require方法在浏览器和NodeJS上完全一样。)

我希望能够做的是在当前模块的上下文中评估脚本 – 也就是说,如果我说exports.a = "100"; 在模块中,我希望在require require.ini模块中的所有代码中的exports.a等于"100"

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

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

在过去的几天里,我一直在搞Node的系统创build模块。 基本上我想创build一些在全新的上下文和variables作用域中调用的模块,为此我将定义一个有限的子集和Node的扩展能力。

我最终在这里研究了他们的源代码 ,并特别关注了NativeModule构造函数及其方法。

你会注意到模块的来源是从一个文件中读取的,包装在一个代表一个函数的string中,并被认为是实际的代码。

包装:

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

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

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

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

我相信你可以在你的代码中做这样的事情,只要你可以得到你想要的模块的源代码。

也许SomeModule.toString()对你来说就足够了。 不知道如何一致的浏览器支持。


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

 process.binding('evals').Script /* { [Function: Script] createContext: [Function], runInContext: [Function], runInThisContext: [Function], runInNewContext: [Function] } */ 

我最终需要使用createContextrunInContext来获得工作,但我猜你可能不需要这样的东西。

(我正在编写一个类库,我希望我的库的require方法在浏览器和NodeJS上完全相同

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

Browserify浏览器端require()用于您的节点模块和npm包

只需在browserify上指定一个或两个javascript文件,它就会使AST以recursion方式读取所有require()。 结果包中包含了你需要的所有东西,包括你可能使用npm安装的库。