gpt4 book ai didi

javascript - 可以卸载、删除或不需要 Nodejs 模块

转载 作者:太空宇宙 更新时间:2023-11-03 21:50:28 25 4
gpt4 key购买 nike

我们正在构建一个 Electron 应用程序,允许用户提供自己的“模块”来运行。我们正在寻找一种方法来需要这些模块,但如果需要的话,然后删除或终止这些模块。我们看过一些似乎讨论这个主题的教程,但我们似乎无法让模块完全终止。我们通过在模块内使用计时器来探索这一点,并且可以观察到即使在删除模块引用后计时器仍在运行。

https://repl.it/repls/QuerulousSorrowfulQuery

index.js

// Load module
let Mod = require('./mod.js');

// Call the module function (which starts a setInterval)
Mod();

// Delete the module after 3 seconds
setTimeout(function () {
Mod = null;
delete Mod;
console.log('Deleted!')
}, 3000);

./mod.js

function Mod() {
setInterval(function () {
console.log('Mod log');
}, 1000);
}

module.exports = Mod;

预期输出

Mod log
Mod log
Deleted!

实际输出

Mod log
Mod log
Deleted!
Mod log
...
(continues to log 'Mod log' indefinitely)

也许我们想得太多了,也许这些模块不会占用内存,但我们加载的模块将具有非常密集的工作负载,并且能够随意停止它们似乎很重要。

根据实际用例进行编辑

这就是我们目前使用该技术的方式。这两个问题是以正确的方式加载模块以及完成后卸载模块。

renderer.js(在浏览器上下文中运行,可以访问文档等)

const webview = document.getElementById('webview'); // A webview object essentially gives us control over a webpage similar to how one can control an iframe in a regular browser.
const url = 'https://ourserver.com/module.js';
let mod;
request({
method: 'get',
url: url,
}, function (err, httpResponse, body) {
if (!err) {
mod = requireFromString(body, url); // Module is loaded
mod(webview); // Module is run
// ...
// Some time later, the module needs to be 'unloaded'.
// We are currently 'unloading' it by dereferencing the 'mod' variable, but as mentioned above, this doesn't really work. So we would like to have a way to wipe the module and timers and etc and free up any memory or resources it was using!
mod = null;
delete mod;
}
})

function requireFromString(src, filename) {
var Module = module.constructor;
var m = new Module();
m._compile(src, filename);
return m.exports;
}

https://ourserver.com/module.js

// This code module will only have access to node modules that are packaged with our app but that is OK for now!
let _ = require('lodash');
let obj = {
key: 'value'
}
async function main(webview) {
console.log(_.get(obj, 'key')) // prints 'value'
webview.loadURL('https://google.com') // loads Google in the web browser
}

module.exports = main;

以防万一读者不熟悉 Electron,renderer.js 可以访问与 iframe 几乎相同的“webview”元素。这就是为什么将其传递给“module.js”将允许模块访问操纵网页,例如更改 URL、单击该网页上的按钮等。

最佳答案

无法终止模块并停止或关闭它正在使用的任何资源。这不是 Node.js 的功能。这样的模块可以有计时器、打开的文件、打开的套接字、运行的服务器等......此外,node.js 不提供“卸载”曾经加载的代码的方法。

您可以从模块缓存中删除模块,但这不会影响现有的、已加载的代码或其资源。

我所知道的唯一万无一失的方法是将用户的模块加载到作为子进程加载的单独的node.js应用程序中,然后您可以退出该进程或终止该进程,然后操作系统将回收它所占用的所有资源使用和卸载内存中的所有内容。这种子进程方案还有一个优点,即用户的代码与主服务器代码更加隔离。如果您愿意,您甚至可以通过在虚拟机中运行其他进程来进一步隔离它。

关于javascript - 可以卸载、删除或不需要 Nodejs 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59915384/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com