javascript - 更改 Node.js 中动态加载模块的全局范围
问题描述
从源动态加载模块:
var src="HERE GOES MY SOURCE"
var Module = module.constructor;
var m = new Module();
m._compile(src, 'a-path-that-does-not-exist');
需要达到以下几点:
- 传递一些变量/函数,以便它们可以在src脚本中全局使用。可以在“m.foo”中设置它们,但希望脚本使用“foo”而不使用“module.foo”。“global.foo”有效,但请参阅第 2 点。
- 如何限制src脚本访问全局范围?
- 如何限制src使用require或其他方式加载其他模块。
- 如何限制src运行异步操作?
解决方案
所有,我能想到的是将脚本包装在它自己的函数中,就像 nodejs 已经为 commonJS 模块所做的那样。这是常规包装。
(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});
如果您使用自己的包装器包装该用户代码,然后当您调用它来执行它时,您可以为 和任何其他半全局符号定义您自己的require
值module
。
如果你也把'use strict'; 作为包装函数的第一行(在任何用户代码之前),那么这将消除对global
对象的默认分配,x = 4
因为如果没有首先明确定义,这将是一个错误x
。如果您随后还创建自己的全局对象并将其作为参数传递,则可以防止任何人分配给真正的全局对象。我认为您不能阻止对预先存在的全局变量的隐式读取访问。
因此,您的包装器可能如下所示:
(function(exports, require, module, __filename, __dirname, global) {
'use strict';
// insert user code here before evaluating it with eval()
// and getting the function which you can then call and pass the desired arguments
});
然后,当你调用这个函数时,你把你想要的所有参数的值传递给它(不是真实的)。
请注意,很难说这种方案的防漏性能到底如何。任何真正的安全都应该在资源受限的虚拟机中运行。
另一个想法,您可以在具有自己的原始全局变量集的工作线程中运行。因此,您完成上述所有操作并在工作线程中运行它。
在评论中解决您的问题:
是否“使用严格”;需要进入包装函数内部还是外部?
它必须是包装函数内的第一行代码,就在您插入用户代码的位置之前。这个想法是强制该包装器内的功能范围(用户代码所在的位置)处于严格模式,以限制它可以做的一些事情。
你能解释一下“我认为你不能阻止对预先存在的全局变量的隐式读取访问。”吗?如果我将自己的对象作为全局对象提供,内部脚本如何访问预先存在的全局对象?
Any code, even strict mode code can access pre-existing globals without the global
prefix. While you can prevent the code from creating new globals by shadowing it with your own global
in the wrapper function arguments and by forcing it into strict mode, you can't prevent strict mode code from reading existing globals because they can do so without the global prefix. So, if there's a pre-existing global called "foo", then existing code can reference that like:
console.log(foo);
or
foo = 12;
If there is no foo
in a closer scope, the interpreter will find the foo
on the global object and use that.
Note that strict mode prevents the automatic creation of a new global with something like:
greeting = "happy birthday"
Could you elaborate more no "resource restricted VM"?
I was talking about real hardware/OS level VMs that allow you to fully control what resources a process may use (disk access, sockets, memory, hardware, etc...). It's essentially a virtual computer environment separate from any other VMs on the same system. This is a more rigorous level of control.
WorkerThread is a very interesting concept. will take a look! My understanding was that WorkerThreads provide memory isolation and the only way to share data is by sending messages (effectively creating copies)?
Yes, Worker Threads provide pretty good isolation as they start up a whole new JS engine and have their own globals. They can shared ArrayBuffers in certain ways (if you choose to do that), but normal JS variables are not accessible across thread boundaries. They would normally communicate via messaging (which is automatically synchronized through the event queue), but you could also communicate via sockets if you wanted.
推荐阅读
- python - Python Scrapy - 从 url 抓取的不是 start_urls 中设置的
- flutter - 在没有 SetState 的情况下调用持久性底页(使用 StreamBuilder)
- python - 如何将列表列表转换为字节?
- php - If Else with isset: else 部分不起作用 [PHP]
- javascript - 谷歌浏览器片段:标识符“...”已被声明
- r - 为相关矩阵选择变量
- c# - console.writeline 数组的值在一行上
- jakarta-ee - Jeddict 可以安装在 Netbeans 11 上吗?
- functional-programming - 重载函数的 Hindley-Milner 类型推断
- javascript - 这段代码有什么问题?为什么它没有按我希望的方式工作..?