在另一个模块的上下文中评估模块
我知道这是非常节点/ 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] } */
我最终需要使用createContext
和runInContext
来获得工作,但我猜你可能不需要这样的东西。
(我正在编写一个类库,我希望我的库的require方法在浏览器和NodeJS上完全相同
如果我理解正确(请原谅我,如果没有;))你正在寻找像node-browserify的东西。
Browserify浏览器端require()用于您的节点模块和npm包
只需在browserify上指定一个或两个javascript文件,它就会使AST以recursion方式读取所有require()。 结果包中包含了你需要的所有东西,包括你可能使用npm安装的库。