如何在运行时重新加载 ES6 模块?

Dev*_*Zot 6 javascript import module node.js

在 ES6 模块之前,通过删除require缓存来强制重新加载 JS 脚本(我从其他 Stack 答案中得知)很容易:

delete require.cache[require.resolve('./mymodule.js')]
Run Code Online (Sandbox Code Playgroud)

但是,我找不到通过import.

这可能足以说明这个问题,但以防万一,这里有一个简化版本的代码。我拥有的是一个运行类似以下内容的节点服务器:

-- look.mjs -- 
var look = function(user) { console.log(user + " looks arond.") }
export { look };

-- parser.mjs -- 
import { look } from './look.mjs';

function parse(user, str) {
    if (str == "look") return look(user);
}
Run Code Online (Sandbox Code Playgroud)

我想要的是能够手动更改 look.mjs 文件(例如修复拼写错误的单词),触发导致在运行时重新导入 look.mjs 的函数,这样 parse() 无需返回新值重启节点服务器。

我尝试更改为动态导入,如下所示:

-- parser.mjs -- 
function parse(user, str) {
    if (str == "look") {
        import('./look.mjs').then(m => m.look(user))
    }
}
Run Code Online (Sandbox Code Playgroud)

这也行不通。(我的意思是,它确实如此,但它不会在每次调用时重新加载 look.mjs,只是第一次)而且如果可能的话,我更愿意继续使用静态导入。

另外,如果这不清楚,这都是服务器端。我不想将新模块传递给客户端,只是让一个节点模块重新加载另一个节点模块。

tar*_*lem 0

我不知道这样做的原因是什么,我认为在运行时更改模块的上下文并导致意外行为是不安全的,这也是 Deno 出现的原因之一。

如果您想在运行时运行一些代码评估,您可以使用 vm 进行类似的操作:https: //nodejs.org/dist/latest-v16.x/docs/api/vm.html