File tree Expand file tree Collapse file tree 4 files changed +60
-29
lines changed Open diff view settings
Expand file tree Collapse file tree 4 files changed +60
-29
lines changed Open diff view settings
Original file line number Diff line number Diff line change @@ -813,6 +813,9 @@ const vm = require('vm');
813813<!-- YAML
814814added: v10.10 .0
815815changes:
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
849862Compiles the given code into the provided context (if no context is
Original file line number Diff line number Diff line change @@ -101,7 +101,6 @@ const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
101101const 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
Original file line number Diff line number Diff 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
Original file line number Diff line number Diff line change 88 Module,
99 SourceTextModule,
1010 SyntheticModule,
11- createContext
11+ createContext,
12+ compileFunction,
1213} = require ( 'vm' ) ;
1314const 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+ }
You can’t perform that action at this time.
0 commit comments