esm: unflag Module.register and allow nested loader import()

Major functional changes:

- Allow `import()` to work within loaders that require other loaders,
- Unflag the use of `Module.register`.

A new interface `Customizations` has been created in order to unify
`ModuleLoader` (previously `DefaultModuleLoader`), `Hooks` and
`CustomizedModuleLoader` all of which now implement it:

```ts
interface LoadResult {
  format: ModuleFormat;
  source: ModuleSource;
}

interface ResolveResult {
  format: string;
  url: URL['href'];
}

interface Customizations {
  allowImportMetaResolve: boolean;
  load(url: string, context: object): Promise<LoadResult>
  resolve(
    originalSpecifier:
    string, parentURL: string,
    importAssertions: Record<string, string>
  ): Promise<ResolveResult>
  resolveSync(
    originalSpecifier:
    string, parentURL: string,
    importAssertions: Record<string, string>
  ) ResolveResult;
  register(specifier: string, parentUrl: string): any;
  forceLoadHooks(): void;
  importMetaInitialize(meta, context, loader): void;
}
```

The `ModuleLoader` class now has `setCustomizations` which takes an
object of this shape and delegates its responsibilities to this object
if present.

Note that two properties `allowImportMetaResolve` and `resolveSync`
exist now as a mechanism for `import.meta.resolve` – since `Hooks`
does not implement `resolveSync` other loaders cannot use
`import.meta.resolve`; `allowImportMetaResolve` is a way of checking
for that case instead of invoking `resolveSync` and erroring.

Fixes https://github.com/nodejs/node/issues/48515
Closes https://github.com/nodejs/node/pull/48439

PR-URL: https://github.com/nodejs/node/pull/48559
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
This commit is contained in:
Izaak Schroeder authored and GitHub committed 2023-07-19 10:33:47 +00:00
1 parent 38cc538453
commit a2fc4a383e
11 files changed
+266 -159

No files matched your search

-17
View File
@@ -1233,23 +1233,6 @@ provided.
Encoding provided to `TextDecoder()` API was not one of the
[WHATWG Supported Encodings][].
<a id="ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE"></a>
### `ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE`
<!-- YAML
added: REPLACEME
-->
Programmatically registering custom ESM loaders
currently requires at least one custom loader to have been
registered via the `--experimental-loader` flag. A no-op
loader registered via CLI is sufficient
(for example: `--experimental-loader data:text/javascript,`;
do not omit the necessary trailing comma).
A future version of Node.js will support the programmatic
registration of loaders without needing to also use the flag.
<a id="ERR_EVAL_ESM_CANNOT_PRINT"></a>
### `ERR_EVAL_ESM_CANNOT_PRINT`