在ES6模块之前,通过删除其require
缓存,强制重新加载JS脚本是很容易的(我从其他Stack答案中得知):
delete require.cache[require.resolve('./mymodule.js')]
但是,我找不到通过import
加载的ES6模块的等效模块。
这可能已经足够让这个问题清楚了,但为了以防万一,这里有一个代码的简化版本,我有一个节点服务器,运行如下代码:
-- 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);
}
我想要的是能够手动更改look.mjs文件(例如,修复拼写错误的单词),触发一个函数,使look.mjs在运行时重新导入,这样parse()就可以返回新值,而不必重新启动节点服务器。
我尝试更改为动态导入,如下所示:
-- parser.mjs --
function parse(user, str) {
if (str == "look") {
import('./look.mjs').then(m => m.look(user))
}
}
这也不起作用。(我的意思是,它起作用了,但是它不会在每次调用时重新加载look.mjs,只是在第一次调用时)如果可能的话,我更喜欢继续使用静态导入。
另外,如果这一点不清楚,这是所有的服务器端。我不试图传递一个新的模块到客户端,只是让一个节点模块重新加载另一个节点模块。
3条答案
按热度按时间wlzqhblo1#
我不知道这样做背后的原因是什么,我认为在运行时更改模块的上下文并导致意外行为是不安全的,这也是Deno选择这样做的原因之一。
如果你想在运行时运行一些代码评估,你可以使用vm来执行类似这样的操作:https://nodejs.org/dist/latest-v16.x/docs/api/vm.html
fnvucqvd2#
您可以尝试在更改代码时使用nodemon动态刷新
https://www.npmjs.com/package/nodemon
xn1cxnb43#
我同意@tarek-salem的观点,最好使用
vm
库。但是有另一种方法可以解决你的问题。没有办法清除你使用的动态导入缓存(顺便说一下,有一种方法可以清除公共导入缓存,因为require
和公共import
具有相同的缓存,而动态import
具有自己的缓存)。但是可以使用require代替动态导入。要执行此操作,请首先在parser.mjs
中创建require那么你有两个选择:
1.更简单:将
look.mjs
转换为commonjs格式(重命名为look.cjs
并使用module.exports
)。1.如果希望能够使用
import
和require
查找.mjs,则应使用package.json创建npm包在这种情况下,在
parser.mjs
中,您将能够使用require('look')
,在其他文件中,您将能够使用import('look')
或import * as look from 'look'
。