I am writing a networked application that needs to load and unload self-contained (approved) code dynamically. The main goal, in short, is to load these scripts for short amounts of time and avoid global name collisions or contaminating the global scope, and being able to unload them and have everything be garbage collected.
The initial problem was that any global variables will persist after unload if I simply add and remove a script in the DOM.
My temporary solution was to wrap all of my individual dynamic code section files in:
systemArray.push((function() {
// local-global scope
function main() {
// do something
}
return main;
}()));
...
...
// some external code calls:
systemArray[sandboxIdx](); // max of 10 sandboxes at once, need to unload old sandboxes that have been exited
and simply pop the array upon unload to let the garbage collector do its work. However, this doesn't really allow for splitting the sub-program into multiple files, and it seems a little error-prone unless I can do some preprocessing on the server-side to create a concatenated file.
Then I looked into ES6 modules. These seem to be fine and avoid name collisions, but it's unclear to me whether modules can ever be unloaded, which is the key thing that I need to do without changing webpages or refreshing.
Firstly, is there a way to unload a module explicitly at runtime? The main, non-unloading part of the application only needs to import one function, but the scripts themselves may have a lot of code. Secondly, if the answer is yes, do any modules that the unloaded module load also get unloaded? Are global variables within the modules correctly garbage collected? If the answer is no, what other options are there?