vm: support using the default loader to handle dynamic import()

This patch adds support for using
`vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER` as
`importModuleDynamically` in all APIs that take the option
except `vm.SourceTextModule`. This allows users to have a shortcut
to support dynamic import() in the compiled code without missing
the compilation cache if they don't need customization of the
loading process. We emit an experimental warning when the
`import()` is actually handled by the default loader through
this option instead of requiring `--experimental-vm-modules`.

In addition this refactors the documentation for
`importModuleDynamically` and adds a dedicated section for it
with examples.

`vm.SourceTextModule` is not supported in this patch because
it needs additional refactoring to handle `initializeImportMeta`,
which can be done in a follow-up.

PR-URL: https://github.com/nodejs/node/pull/51244
Fixes: https://github.com/nodejs/node/issues/51154
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
Joyee Cheung 2024-02-01 12:45:42 +01:00 committed by GitHub
parent dd4767f99f
commit ad0bcb9c02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 593 additions and 192 deletions

View file

@ -23,6 +23,7 @@
const {
ArrayPrototypeForEach,
ObjectFreeze,
Symbol,
PromiseReject,
ReflectApply,
@ -61,6 +62,9 @@ const {
isContext,
registerImportModuleDynamically,
} = require('internal/vm');
const {
vm_dynamic_import_main_context_default,
} = internalBinding('symbols');
const kParsingContext = Symbol('script parsing context');
class Script extends ContextifyScript {
@ -108,9 +112,7 @@ class Script extends ContextifyScript {
throw e; /* node-do-not-add-exception-line */
}
if (importModuleDynamically !== undefined) {
registerImportModuleDynamically(this, importModuleDynamically);
}
registerImportModuleDynamically(this, importModuleDynamically);
}
runInThisContext(options) {
@ -245,9 +247,7 @@ function createContext(contextObject = {}, options = kEmptyObject) {
makeContext(contextObject, name, origin, strings, wasm, microtaskQueue, hostDefinedOptionId);
// Register the context scope callback after the context was initialized.
if (importModuleDynamically !== undefined) {
registerImportModuleDynamically(contextObject, importModuleDynamically);
}
registerImportModuleDynamically(contextObject, importModuleDynamically);
return contextObject;
}
@ -378,6 +378,13 @@ function measureMemory(options = kEmptyObject) {
return result;
}
const vmConstants = {
__proto__: null,
USE_MAIN_CONTEXT_DEFAULT_LOADER: vm_dynamic_import_main_context_default,
};
ObjectFreeze(vmConstants);
module.exports = {
Script,
createContext,
@ -388,6 +395,7 @@ module.exports = {
isContext,
compileFunction,
measureMemory,
constants: vmConstants,
};
// The vm module is patched to include vm.Module, vm.SourceTextModule