我知道这非常非节点/ CommonJS-y原谅我。 (我正在编写各种类型的库,我希望我的库require
方法在浏览器和NodeJS上完全相同。)
我想要做的是在当前模块的上下文中评估脚本 - 也就是说,如果我在模块中说exports.a = "100";
,我想要{{1}在exports.a
之后的"100"
模块中的所有代码中等于require
。
如果不清楚,我很乐意详细说明。
答案 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] }
*/
我最终需要使用createContext
和runInContext
让事情有效,但我猜你可能不会需要这样的事情。
答案 1 :(得分:0)
(我正在写一个各种类型的库,我想要我的库需要 在浏览器和NodeJS上完全相同的方法
如果我理解正确(如果没有,请原谅我;))你正在寻找像node-browserify这样的东西。
Browserify浏览器端require()用于节点模块和npm 封装
只需在browserify上指向一两个javascript文件即可 AST以递归方式读取所有require()。得到的捆绑包有 您需要的一切,包括拉入您可能拥有的库 使用npm安装!