当 importModuleDynamically 是函数时


¥When importModuleDynamically is a function

importModuleDynamically 是一个函数时,当编译代码中调用 import() 时,它将被调用,以便用户自定义所请求的模块应如何编译和评估。目前,必须使用 --experimental-vm-modules 标志启动 Node.js 实例才能使此选项发挥作用。如果未设置该标志,则该回调将被忽略。如果评估的代码实际上调用了 import(),则结果将拒绝并显示 ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG

¥When importModuleDynamically is a function, it will be invoked when import() is called in the compiled code for users to customize how the requested module should be compiled and evaluated. Currently, the Node.js instance must be launched with the --experimental-vm-modules flag for this option to work. If the flag isn't set, this callback will be ignored. If the code evaluated actually calls to import(), the result will reject with ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG.

回调 importModuleDynamically(specifier, referrer, importAttributes) 具有以下签名:

¥The callback importModuleDynamically(specifier, referrer, importAttributes) has the following signature:

  • specifier <string> 说明符传递给 import()

    ¥specifier <string> specifier passed to import()

  • referrer <vm.Script> | <Function> | <vm.SourceTextModule> | <Object> 引用者是针对 new vm.Scriptvm.runInThisContextvm.runInContextvm.runInNewContext 编译的 vm.Scriptvm.compileFunction 是编译后的 Functionnew vm.SourceTextModule 是编译后的 vm.SourceTextModulevm.createContext() 是上下文 Object

    ¥referrer <vm.Script> | <Function> | <vm.SourceTextModule> | <Object> The referrer is the compiled vm.Script for new vm.Script, vm.runInThisContext, vm.runInContext and vm.runInNewContext. It's the compiled Function for vm.compileFunction, the compiled vm.SourceTextModule for new vm.SourceTextModule, and the context Object for vm.createContext().

  • importAttributes <Object> 传给 optionsExpression 可选参数的 "with" 值,如果没有提供值,则为空对象。

    ¥importAttributes <Object> The "with" value passed to the optionsExpression optional parameter, or an empty object if no value was provided.

  • 返回:<Module Namespace Object> | <vm.Module> 建议返回 vm.Module 以利用错误跟踪,并避免包含 then 函数导出的命名空间出现问题。

    ¥Returns: <Module Namespace Object> | <vm.Module> Returning a vm.Module is recommended in order to take advantage of error tracking, and to avoid issues with namespaces that contain then function exports.

// This script must be run with --experimental-vm-modules.
import { Script, SyntheticModule } from 'node:vm';

const script = new Script('import("foo.json", { with: { type: "json" } })', {
  async importModuleDynamically(specifier, referrer, importAttributes) {
    console.log(specifier);  // 'foo.json'
    console.log(referrer);   // The compiled script
    console.log(importAttributes);  // { type: 'json' }
    const m = new SyntheticModule(['bar'], () => { });
    await m.link(() => { });
    m.setExport('bar', { hello: 'world' });
    return m;
  },
});
const result = await script.runInThisContext();
console.log(result);  //  { bar: { hello: 'world' } }// This script must be run with --experimental-vm-modules.
const { Script, SyntheticModule } = require('node:vm');

(async function main() {
  const script = new Script('import("foo.json", { with: { type: "json" } })', {
    async importModuleDynamically(specifier, referrer, importAttributes) {
      console.log(specifier);  // 'foo.json'
      console.log(referrer);   // The compiled script
      console.log(importAttributes);  // { type: 'json' }
      const m = new SyntheticModule(['bar'], () => { });
      await m.link(() => { });
      m.setExport('bar', { hello: 'world' });
      return m;
    },
  });
  const result = await script.runInThisContext();
  console.log(result);  //  { bar: { hello: 'world' } }
})();