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 66a14d3

Browse filesBrowse files
devsnekdanielleadams
authored andcommitted
vm: add importModuleDynamically option to compileFunction
This reverts commit 2d5d773. See: #32985 See: #33364 See: #33166 Fixes: #31860 PR-URL: #35431 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Ujjwal Sharma <ryzokuken@disroot.org>
1 parent 8a25405 commit 66a14d3
Copy full SHA for 66a14d3

File tree

Expand file treeCollapse file tree

4 files changed

+60
-29
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+60
-29
lines changed
Open diff view settings
Collapse file

‎doc/api/vm.md‎

Copy file name to clipboardExpand all lines: doc/api/vm.md
+13Lines changed: 13 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,9 @@ const vm = require('vm');
813813
<!-- YAML
814814
added: v10.10.0
815815
changes:
816+
- version: REPLACEME
817+
pr-url: https://github.com/nodejs/node/pull/35431
818+
description: Added `importModuleDynamically` option again.
816819
- version: v14.3.0
817820
pr-url: https://github.com/nodejs/node/pull/33364
818821
description: Removal of `importModuleDynamically` due to compatibility
@@ -844,6 +847,16 @@ changes:
844847
* `contextExtensions` {Object[]} An array containing a collection of context
845848
extensions (objects wrapping the current scope) to be applied while
846849
compiling. **Default:** `[]`.
850+
* `importModuleDynamically` {Function} Called during evaluation of this module
851+
when `import()` is called. If this option is not specified, calls to
852+
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
853+
This option is part of the experimental modules API, and should not be
854+
considered stable.
855+
* `specifier` {string} specifier passed to `import()`
856+
* `function` {Function}
857+
* Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is
858+
recommended in order to take advantage of error tracking, and to avoid
859+
issues with namespaces that contain `then` function exports.
847860
* Returns: {Function}
848861

849862
Compiles the given code into the provided context (if no context is
Collapse file

‎lib/internal/modules/cjs/loader.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/cjs/loader.js
+12-28Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
101101
const policy = getOptionValue('--experimental-policy') ?
102102
require('internal/process/policy') :
103103
null;
104-
const { compileFunction } = internalBinding('contextify');
105104

106105
// Whether any user-provided CJS modules had been loaded (executed).
107106
// Used for internal assertions.
@@ -1019,40 +1018,25 @@ function wrapSafe(filename, content, cjsModuleInstance) {
10191018
},
10201019
});
10211020
}
1022-
let compiled;
10231021
try {
1024-
compiled = compileFunction(
1025-
content,
1022+
return vm.compileFunction(content, [
1023+
'exports',
1024+
'require',
1025+
'module',
1026+
'__filename',
1027+
'__dirname',
1028+
], {
10261029
filename,
1027-
0,
1028-
0,
1029-
undefined,
1030-
false,
1031-
undefined,
1032-
[],
1033-
[
1034-
'exports',
1035-
'require',
1036-
'module',
1037-
'__filename',
1038-
'__dirname',
1039-
]
1040-
);
1030+
importModuleDynamically(specifier) {
1031+
const loader = asyncESM.ESMLoader;
1032+
return loader.import(specifier, normalizeReferrerURL(filename));
1033+
},
1034+
});
10411035
} catch (err) {
10421036
if (process.mainModule === cjsModuleInstance)
10431037
enrichCJSError(err);
10441038
throw err;
10451039
}
1046-
1047-
const { callbackMap } = internalBinding('module_wrap');
1048-
callbackMap.set(compiled.cacheKey, {
1049-
importModuleDynamically: async (specifier) => {
1050-
const loader = asyncESM.ESMLoader;
1051-
return loader.import(specifier, normalizeReferrerURL(filename));
1052-
}
1053-
});
1054-
1055-
return compiled.function;
10561040
}
10571041

10581042
// Run the file contents in the correct scope or sandbox. Expose
Collapse file

‎lib/vm.js‎

Copy file name to clipboardExpand all lines: lib/vm.js
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ function compileFunction(code, params, options = {}) {
324324
produceCachedData = false,
325325
parsingContext = undefined,
326326
contextExtensions = [],
327+
importModuleDynamically,
327328
} = options;
328329

329330
validateString(filename, 'options.filename');
@@ -371,6 +372,22 @@ function compileFunction(code, params, options = {}) {
371372
result.function.cachedData = result.cachedData;
372373
}
373374

375+
if (importModuleDynamically !== undefined) {
376+
if (typeof importModuleDynamically !== 'function') {
377+
throw new ERR_INVALID_ARG_TYPE('options.importModuleDynamically',
378+
'function',
379+
importModuleDynamically);
380+
}
381+
const { importModuleDynamicallyWrap } =
382+
require('internal/vm/module');
383+
const { callbackMap } = internalBinding('module_wrap');
384+
const wrapped = importModuleDynamicallyWrap(importModuleDynamically);
385+
const func = result.function;
386+
callbackMap.set(result.cacheKey, {
387+
importModuleDynamically: (s, _k) => wrapped(s, func),
388+
});
389+
}
390+
374391
return result.function;
375392
}
376393

Collapse file

‎test/parallel/test-vm-module-basic.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-vm-module-basic.js
+18-1Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const {
88
Module,
99
SourceTextModule,
1010
SyntheticModule,
11-
createContext
11+
createContext,
12+
compileFunction,
1213
} = require('vm');
1314
const util = require('util');
1415

@@ -160,3 +161,19 @@ const util = require('util');
160161
name: 'TypeError'
161162
});
162163
}
164+
165+
// Test compileFunction importModuleDynamically
166+
{
167+
const module = new SyntheticModule([], () => {});
168+
module.link(() => {});
169+
const f = compileFunction('return import("x")', [], {
170+
importModuleDynamically(specifier, referrer) {
171+
assert.strictEqual(specifier, 'x');
172+
assert.strictEqual(referrer, f);
173+
return module;
174+
},
175+
});
176+
f().then((ns) => {
177+
assert.strictEqual(ns, module.namespace);
178+
});
179+
}

0 commit comments

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