Skip to content

Commit 4143c74

Browse files
devsnekBethGriggs
authored andcommitted
vm: add importModuleDynamically option to compileFunction
Fixes: #31860 PR-URL: #32985 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
1 parent c21f1f0 commit 4143c74

File tree

5 files changed

+63
-30
lines changed

5 files changed

+63
-30
lines changed

‎doc/api/vm.md‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ changes:
8888
This option is part of the experimental modules API, and should not be
8989
considered stable.
9090
*`specifier`{string} specifier passed to `import()`
91-
*`module`{vm.Module}
91+
*`script`{vm.Script}
9292
* Returns:{Module Namespace Object|vm.Module} Returning a `vm.Module` is
9393
recommended in order to take advantage of error tracking, and to avoid
9494
issues with namespaces that contain `then` function exports.
@@ -773,6 +773,10 @@ const vm = require('vm');
773773
## `vm.compileFunction(code[, params[, options]])`
774774
<!--YAML
775775
added: v10.10.0
776+
changes:
777+
- version:REPLACEME
778+
pr-url: https://github.com/nodejs/node/pull/32985
779+
description: The `importModuleDynamically` option is now supported.
776780
-->
777781

778782
*`code`{string} The body of the function to compile.
@@ -795,6 +799,16 @@ added: v10.10.0
795799
* `contextExtensions`{Object[]} An array containing a collection of context
796800
extensions (objectswrappingthecurrentscope) to be applied while
797801
compiling. **Default:** `[]`.
802+
* `importModuleDynamically`{Function} Called during evaluation ofthismodule
803+
when `import()` is called. Ifthis option is not specified, calls to
804+
`import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][].
805+
This option is part of the experimental modules API, and should not be
806+
considered stable.
807+
*`specifier`{string} specifier passed to `import()`
808+
*`function`{Function}
809+
* Returns:{Module Namespace Object|vm.Module} Returning a `vm.Module` is
810+
recommended in order to take advantage of error tracking, and to avoid
811+
issues with namespaces that contain `then`function exports.
798812
* Returns:{Function}
799813

800814
Compiles the given code into the provided context (ifnocontextis

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

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
7777
constmanifest=getOptionValue('--experimental-policy') ?
7878
require('internal/process/policy').manifest :
7979
null;
80-
const{ compileFunction }=internalBinding('contextify');
8180

8281
// Whether any user-provided CJS modules had been loaded (executed).
8382
// Used for internal assertions.
@@ -1100,40 +1099,25 @@ function wrapSafe(filename, content, cjsModuleInstance){
11001099
},
11011100
});
11021101
}
1103-
letcompiled;
11041102
try{
1105-
compiled=compileFunction(
1106-
content,
1103+
returnvm.compileFunction(content,[
1104+
'exports',
1105+
'require',
1106+
'module',
1107+
'__filename',
1108+
'__dirname',
1109+
],{
11071110
filename,
1108-
0,
1109-
0,
1110-
undefined,
1111-
false,
1112-
undefined,
1113-
[],
1114-
[
1115-
'exports',
1116-
'require',
1117-
'module',
1118-
'__filename',
1119-
'__dirname',
1120-
]
1121-
);
1111+
importModuleDynamically(specifier){
1112+
constloader=asyncESM.ESMLoader;
1113+
returnloader.import(specifier,normalizeReferrerURL(filename));
1114+
},
1115+
});
11221116
}catch(err){
11231117
if(process.mainModule===cjsModuleInstance)
11241118
enrichCJSError(err);
11251119
throwerr;
11261120
}
1127-
1128-
const{ callbackMap }=internalBinding('module_wrap');
1129-
callbackMap.set(compiled.cacheKey,{
1130-
importModuleDynamically: async(specifier)=>{
1131-
constloader=asyncESM.ESMLoader;
1132-
returnloader.import(specifier,normalizeReferrerURL(filename));
1133-
}
1134-
});
1135-
1136-
returncompiled.function;
11371121
}
11381122

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

‎lib/vm.js‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ function compileFunction(code, params, options ={}){
313313
produceCachedData =false,
314314
parsingContext =undefined,
315315
contextExtensions =[],
316+
importModuleDynamically,
316317
}=options;
317318

318319
validateString(filename,'options.filename');
@@ -360,6 +361,22 @@ function compileFunction(code, params, options ={}){
360361
result.function.cachedData=result.cachedData;
361362
}
362363

364+
if(importModuleDynamically!==undefined){
365+
if(typeofimportModuleDynamically!=='function'){
366+
thrownewERR_INVALID_ARG_TYPE('options.importModuleDynamically',
367+
'function',
368+
importModuleDynamically);
369+
}
370+
const{ importModuleDynamicallyWrap }=
371+
require('internal/vm/module');
372+
const{ callbackMap }=internalBinding('module_wrap');
373+
constwrapped=importModuleDynamicallyWrap(importModuleDynamically);
374+
constfunc=result.function;
375+
callbackMap.set(result.cacheKey,{
376+
importModuleDynamically: (s,_k)=>wrapped(s,func),
377+
});
378+
}
379+
363380
returnresult.function;
364381
}
365382

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

Lines 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
constutil=require('util');
1415

@@ -147,3 +148,19 @@ const util = require('util');
147148
name: 'TypeError'
148149
});
149150
}
151+
152+
// Test compileFunction importModuleDynamically
153+
{
154+
constmodule=newSyntheticModule([],()=>{});
155+
module.link(()=>{});
156+
constf=compileFunction('return import("x")',[],{
157+
importModuleDynamically(specifier,referrer){
158+
assert.strictEqual(specifier,'x');
159+
assert.strictEqual(referrer,f);
160+
returnmodule;
161+
},
162+
});
163+
f().then((ns)=>{
164+
assert.strictEqual(ns,module.namespace);
165+
});
166+
}

‎tools/doc/type-parser.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ const customTypesMap ={
148148
'URLSearchParams': 'url.html#url_class_urlsearchparams',
149149

150150
'vm.Module': 'vm.html#vm_class_vm_module',
151+
'vm.Script': 'vm.html#vm_class_vm_script',
151152
'vm.SourceTextModule': 'vm.html#vm_class_vm_sourcetextmodule',
152153

153154
'MessagePort': 'worker_threads.html#worker_threads_class_messageport',

0 commit comments

Comments
(0)