mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
Split `module.link(linker)` into two synchronous step `sourceTextModule.linkRequests()` and `sourceTextModule.instantiate()`. This allows creating vm modules and resolving the dependencies in a complete synchronous procedure. This also makes `syntheticModule.link()` redundant. The link step for a SyntheticModule is no-op and is already taken care in the constructor by initializing the binding slots with the given export names. PR-URL: https://github.com/nodejs/node/pull/59000 Refs: https://github.com/nodejs/node/issues/37648 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
73 lines
1.8 KiB
JavaScript
73 lines
1.8 KiB
JavaScript
'use strict';
|
|
|
|
// Flags: --experimental-vm-modules --js-source-phase-imports
|
|
|
|
require('../common');
|
|
|
|
const assert = require('assert');
|
|
|
|
const { SourceTextModule } = require('vm');
|
|
const test = require('node:test');
|
|
|
|
test('basic circular linking', async function circular() {
|
|
const foo = new SourceTextModule(`
|
|
import getFoo from 'bar';
|
|
export let foo = 42;
|
|
export default getFoo();
|
|
`);
|
|
const bar = new SourceTextModule(`
|
|
import { foo } from 'foo';
|
|
export default function getFoo() {
|
|
return foo;
|
|
}
|
|
`);
|
|
foo.linkRequests([bar]);
|
|
bar.linkRequests([foo]);
|
|
|
|
foo.instantiate();
|
|
assert.strictEqual(foo.status, 'linked');
|
|
assert.strictEqual(bar.status, 'linked');
|
|
|
|
await foo.evaluate();
|
|
assert.strictEqual(foo.namespace.default, 42);
|
|
});
|
|
|
|
test('circular linking graph', async function circular2() {
|
|
const sourceMap = {
|
|
'root': `
|
|
import * as a from './a.mjs';
|
|
import * as b from './b.mjs';
|
|
if (!('fromA' in a))
|
|
throw new Error();
|
|
if (!('fromB' in a))
|
|
throw new Error();
|
|
if (!('fromA' in b))
|
|
throw new Error();
|
|
if (!('fromB' in b))
|
|
throw new Error();
|
|
`,
|
|
'./a.mjs': `
|
|
export * from './b.mjs';
|
|
export let fromA;
|
|
`,
|
|
'./b.mjs': `
|
|
export * from './a.mjs';
|
|
export let fromB;
|
|
`
|
|
};
|
|
const moduleMap = new Map();
|
|
for (const [specifier, source] of Object.entries(sourceMap)) {
|
|
moduleMap.set(specifier, new SourceTextModule(source, {
|
|
identifier: new URL(specifier, 'file:///').href,
|
|
}));
|
|
}
|
|
for (const mod of moduleMap.values()) {
|
|
mod.linkRequests(mod.moduleRequests.map((request) => {
|
|
return moduleMap.get(request.specifier);
|
|
}));
|
|
}
|
|
const rootModule = moduleMap.get('root');
|
|
rootModule.instantiate();
|
|
await rootModule.evaluate();
|
|
});
|