@@ -408,7 +408,78 @@ This implementation lies at a lower level than the [ECMAScript Module
408
408
loader] [ ] . There is also no way to interact with the Loader yet, though
409
409
support is planned.
410
410
411
- ``` js
411
+ ``` mjs
412
+ import vm from ' vm' ;
413
+
414
+ const contextifiedObject = vm .createContext ({
415
+ secret: 42 ,
416
+ print: console .log ,
417
+ });
418
+
419
+ // Step 1
420
+ //
421
+ // Create a Module by constructing a new `vm.SourceTextModule` object. This
422
+ // parses the provided source text, throwing a `SyntaxError` if anything goes
423
+ // wrong. By default, a Module is created in the top context. But here, we
424
+ // specify `contextifiedObject` as the context this Module belongs to.
425
+ //
426
+ // Here, we attempt to obtain the default export from the module "foo", and
427
+ // put it into local binding "secret".
428
+
429
+ const bar = new vm.SourceTextModule (`
430
+ import s from 'foo';
431
+ s;
432
+ print(s);
433
+ ` , { context: contextifiedObject });
434
+
435
+ // Step 2
436
+ //
437
+ // "Link" the imported dependencies of this Module to it.
438
+ //
439
+ // The provided linking callback (the "linker") accepts two arguments: the
440
+ // parent module (`bar` in this case) and the string that is the specifier of
441
+ // the imported module. The callback is expected to return a Module that
442
+ // corresponds to the provided specifier, with certain requirements documented
443
+ // in `module.link()`.
444
+ //
445
+ // If linking has not started for the returned Module, the same linker
446
+ // callback will be called on the returned Module.
447
+ //
448
+ // Even top-level Modules without dependencies must be explicitly linked. The
449
+ // callback provided would never be called, however.
450
+ //
451
+ // The link() method returns a Promise that will be resolved when all the
452
+ // Promises returned by the linker resolve.
453
+ //
454
+ // Note: This is a contrived example in that the linker function creates a new
455
+ // "foo" module every time it is called. In a full-fledged module system, a
456
+ // cache would probably be used to avoid duplicated modules.
457
+
458
+ async function linker (specifier , referencingModule ) {
459
+ if (specifier === ' foo' ) {
460
+ return new vm.SourceTextModule (`
461
+ // The "secret" variable refers to the global variable we added to
462
+ // "contextifiedObject" when creating the context.
463
+ export default secret;
464
+ ` , { context: referencingModule .context });
465
+
466
+ // Using `contextifiedObject` instead of `referencingModule.context`
467
+ // here would work as well.
468
+ }
469
+ throw new Error (` Unable to resolve dependency: ${ specifier} ` );
470
+ }
471
+ await bar .link (linker);
472
+
473
+ // Step 3
474
+ //
475
+ // Evaluate the Module. The evaluate() method returns a promise which will
476
+ // resolve after the module has finished evaluating.
477
+
478
+ // Prints 42.
479
+ await bar .evaluate ();
480
+ ```
481
+
482
+ ``` cjs
412
483
const vm = require (' vm' );
413
484
414
485
const contextifiedObject = vm .createContext ({
@@ -542,8 +613,7 @@ The identifier of the current module, as set in the constructor.
542
613
543
614
* ` linker ` {Function}
544
615
* ` specifier ` {string} The specifier of the requested module:
545
- <!-- eslint-skip -->
546
- ``` js
616
+ ``` mjs
547
617
import foo from ' foo' ;
548
618
// ^^^^^ the module specifier
549
619
```
@@ -673,11 +743,37 @@ Properties assigned to the `import.meta` object that are objects may
673
743
allow the module to access information outside the specified `context`. Use
674
744
`vm.runInContext()` to create objects in a specific context.
675
745
676
- ```js
677
- const vm = require( ' vm' ) ;
746
+ ```mjs
747
+ import vm from ' vm' ;
678
748
679
749
const contextifiedObject = vm.createContext({ secret: 42 });
680
750
751
+ const module = new vm.SourceTextModule(
752
+ ' Object .getPrototypeOf (import .meta.prop).secret = secret;' ,
753
+ {
754
+ initializeImportMeta(meta) {
755
+ // Note: this object is created in the top context. As such,
756
+ // Object.getPrototypeOf(import.meta.prop) points to the
757
+ // Object.prototype in the top context rather than that in
758
+ // the contextified object.
759
+ meta.prop = {};
760
+ }
761
+ });
762
+ // Since module has no dependencies, the linker function will never be called.
763
+ await module.link(() => {});
764
+ await module.evaluate();
765
+
766
+ // Now, Object.prototype.secret will be equal to 42.
767
+ //
768
+ // To fix this problem, replace
769
+ // meta.prop = {};
770
+ // above with
771
+ // meta.prop = vm.runInContext(' {}' , contextifiedObject);
772
+ ```
773
+
774
+ ```cjs
775
+ const vm = require(' vm' );
776
+ const contextifiedObject = vm.createContext({ secret: 42 });
681
777
(async () => {
682
778
const module = new vm.SourceTextModule(
683
779
' Object .getPrototypeOf (import .meta.prop).secret = secret;' ,
@@ -693,7 +789,6 @@ const contextifiedObject = vm.createContext({ secret: 42 });
693
789
// Since module has no dependencies, the linker function will never be called.
694
790
await module.link(() => {});
695
791
await module.evaluate();
696
-
697
792
// Now, Object.prototype.secret will be equal to 42.
698
793
//
699
794
// To fix this problem, replace
@@ -794,17 +889,27 @@ This method is used after the module is linked to set the values of exports. If
794
889
it is called before the module is linked, an [` ERR_VM_MODULE_STATUS` ][] error
795
890
will be thrown.
796
891
797
- ` ` ` js
798
- const vm = require( 'vm') ;
892
+ ` ` ` mjs
893
+ import vm from 'vm';
799
894
895
+ const m = new vm.SyntheticModule(['x'], () => {
896
+ m.setExport('x', 1);
897
+ });
898
+
899
+ await m.link(() => {});
900
+ await m.evaluate();
901
+
902
+ assert.strictEqual(m.namespace.x, 1);
903
+ ` ` `
904
+
905
+ ` ` ` cjs
906
+ const vm = require('vm');
800
907
(async () => {
801
908
const m = new vm.SyntheticModule(['x'], () => {
802
909
m.setExport('x', 1);
803
910
});
804
-
805
911
await m.link(() => {});
806
912
await m.evaluate();
807
-
808
913
assert.strictEqual(m.namespace.x, 1);
809
914
})();
810
915
` ` `
0 commit comments