Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e10dc7b

Browse filesBrowse files
legendecasaduh95
authored andcommitted
module: allow overriding linked requests for a ModuleWrap
This allows overriding linked requests for a `ModuleWrap`. The `statusOverride` in `vm.SourceTextModule` could call `moduleWrap.link` a second time when `statusOverride` of `linking` is set to undefined. Overriding of linked requests should be no harm but better to be avoided. However, this will require a follow-up fix on `statusOverride` in `vm.SourceTextModule`. PR-URL: #59527 Backport-PR-URL: #60152 Fixes: #59480 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
1 parent 84701ff commit e10dc7b
Copy full SHA for e10dc7b

File tree

Expand file treeCollapse file tree

2 files changed

+82
-10
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+82
-10
lines changed
Open diff view settings
Collapse file

‎src/module_wrap.cc‎

Copy file name to clipboardExpand all lines: src/module_wrap.cc
-10Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -575,23 +575,13 @@ void ModuleWrap::GetModuleRequests(const FunctionCallbackInfo<Value>& args) {
575575

576576
// moduleWrap.link(moduleWraps)
577577
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
578-
Realm* realm = Realm::GetCurrent(args);
579578
Isolate* isolate = args.GetIsolate();
580579

581580
ModuleWrap* dependent;
582581
ASSIGN_OR_RETURN_UNWRAP(&dependent, args.This());
583582

584583
CHECK_EQ(args.Length(), 1);
585584

586-
Local<Data> linked_requests =
587-
args.This()->GetInternalField(kLinkedRequestsSlot);
588-
if (linked_requests->IsValue() &&
589-
!linked_requests.As<Value>()->IsUndefined()) {
590-
// If the module is already linked, we should not link it again.
591-
THROW_ERR_VM_MODULE_LINK_FAILURE(realm->env(), "module is already linked");
592-
return;
593-
}
594-
595585
Local<FixedArray> requests =
596586
dependent->module_.Get(isolate)->GetModuleRequests();
597587
Local<Array> modules = args[0].As<Array>();
Collapse file
+82Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Flags: --experimental-vm-modules
2+
3+
'use strict';
4+
5+
const common = require('../common');
6+
const vm = require('vm');
7+
const assert = require('assert');
8+
9+
// This test verifies that a module can be returned multiple
10+
// times in the linker function in `module.link(linker)`.
11+
// `module.link(linker)` should handle the race condition of
12+
// `module.status` when the linker function is asynchronous.
13+
14+
// Regression of https://github.com/nodejs/node/issues/59480
15+
16+
const sources = {
17+
'./index.js': `
18+
import foo from "./foo.js";
19+
import shared from "./shared.js";
20+
export default {
21+
foo,
22+
shared
23+
};
24+
`,
25+
'./foo.js': `
26+
import shared from "./shared.js";
27+
export default {
28+
name: "foo"
29+
};
30+
`,
31+
'./shared.js': `
32+
export default {
33+
name: "shared",
34+
};
35+
`,
36+
};
37+
38+
const moduleCache = new Map();
39+
40+
function getModuleInstance(identifier) {
41+
let module = moduleCache.get(identifier);
42+
43+
if (!module) {
44+
module = new vm.SourceTextModule(sources[identifier], {
45+
identifier,
46+
});
47+
moduleCache.set(identifier, module);
48+
}
49+
50+
return module;
51+
}
52+
53+
async function esmImport(identifier) {
54+
const module = getModuleInstance(identifier);
55+
const requests = [];
56+
57+
await module.link(async (specifier, referrer) => {
58+
requests.push([specifier, referrer.identifier]);
59+
// Use `Promise.resolve` to defer a tick to create a race condition on
60+
// `module.status` when a module is being imported several times.
61+
return Promise.resolve(getModuleInstance(specifier));
62+
});
63+
64+
await module.evaluate();
65+
return [module.namespace, requests];
66+
}
67+
68+
async function test() {
69+
const { 0: mod, 1: requests } = await esmImport('./index.js');
70+
assert.strictEqual(mod.default.foo.name, 'foo');
71+
assert.strictEqual(mod.default.shared.name, 'shared');
72+
73+
// Assert that there is no duplicated requests.
74+
assert.deepStrictEqual(requests, [
75+
// [specifier, referrer]
76+
['./foo.js', './index.js'],
77+
['./shared.js', './index.js'],
78+
['./shared.js', './foo.js'],
79+
]);
80+
}
81+
82+
test().then(common.mustCall());

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.