Let's say we are creating a module called app
by constructing a new vm.SourceTextModule
object:
const context = {
exports: {},
console, // custom console object
};
const sandbox = vm.createContext(context);
const app = new vm.SourceTextModule(
`import path from 'path';
console.log(path.resolve('./src'));`,
{
context: sandbox,
}
);
According to the Node.js documentation to obtain the default export from path
module we should "link" the imported dependencies of app
module to it.
To achieve this we should pass linker
callback to app.link
method:
async function linker(specifier, referencingModule) {
// the desired logic...
}
await app.link(linker);
How to implement linker
function properly so that we could import path
module in newly created app
module and use it:
await app.evaluate(); // => /home/user/Documents/project/src
P.S. We are using TypeScript
, so I checked if we have installed types for path
package.
package.json:
"@types/node": "^17.0.31",
I found https://github.com/nodejs/node/issues/35848 where someone posted a code snippet.
From there I've adapted the following linker callback:
The code snippet from the GitHub issue didn't work for me on Node 18.7.0 as is, because the evaluator callback passed to the constructor ofSyntheticModule
is somehow called withthis
set toundefined
. This may be a Node bug.I also cached the imported SyntheticModules in a Map because if they have internal state, creating a new SyntheticModule every time will reset that state.