node.js:使模块使用本地`window`变量

slhcrj9b  于 2023-05-17  发布在  Node.js
关注(0)|答案(2)|浏览(150)

我有这样一个功能与进口的模块,我不能编辑

function create() {
  const window = {}; // Normally initialized by JSDOM to make fake window
  const appboy = require("@braze/web-sdk");
}

我想要的是appboycreate函数中看到本地window
我想避免globalThis.window,因为create函数在并发运行时会出现竞争条件。

xmjla07d

xmjla07d1#

除非@braze/web-sdk显式地提供了一种方法,否则您不能这样做。代码可用的变量是由代码定义的范围内的内容决定的,而不是从哪里使用。除非该模块提供了某种方式来传递this的值(从问题中我猜它没有),否则影响它所看到的window的唯一方法是创建/覆盖全局,因为这是您的代码和模块的唯一共同作用域。
根据您正在处理的约束,一个选项可能是派生模块,添加必要的功能,并在代码中使用该派生模块(甚至可能提供原始的pull请求)。

jdgnovmf

jdgnovmf2#

正如我在上面的评论中提到的,有一个解决方案,我们可以指定自己的自定义全局上下文。
Node有原生的VM模块,可以使用沙箱脚本。
这些沙盒脚本可以有自己的上下文。
这里有一个例子,它是如何工作的,以指出我们正确的方式。
假设我们有一个小剧本

console.log(window)

根据环境的不同,如果我们在浏览器中运行它,它可以打印出全局Window对象,或者在Node.JS中抛出RefferenceError
vm.createContext的帮助下,我们可以创建自己的window并将其指定给脚本。

const vm = require('node:vm');  

// plain object for our purposes
const customGlobal = {
  window: 'Fake window',
  console //console should be passed to let our script option to use it
};  

// plain string with valid js script
const code = 'console.log(window)';  

// here we wrap code into executable environment
const script = new vm.Script(code);

// creating context from our plain object
const context = vm.createContext(customGlobal);

现在,我们只需要将上下文附加到脚本并运行它

script.runInContext(context);

执行的结果将是控制台中的Fake window文本。
通过这个简单的例子,我们现在知道我们可以将类似的方法应用于外部node_modules。
我想相信这本书会引导你解决这个问题。

相关问题