Skip to content

Commit 8b54f01

Browse files
JakobJingleheimerRafaelGSS
authored andcommitted
esm,loader: tidy ESMLoader internals
PR-URL: #44701 Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent dffc204 commit 8b54f01

File tree

3 files changed

+75
-77
lines changed

3 files changed

+75
-77
lines changed

lib/internal/modules/esm/get_format.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
'use strict';
22
const {
33
RegExpPrototypeExec,
4-
ObjectAssign,
5-
ObjectCreate,
64
ObjectPrototypeHasOwnProperty,
75
PromisePrototypeThen,
86
PromiseResolve,
@@ -25,13 +23,14 @@ const { getPackageType, getPackageScopeConfig } = require('internal/modules/esm/
2523
const { URL, fileURLToPath } = require('internal/url');
2624
const { ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
2725

28-
const protocolHandlers = ObjectAssign(ObjectCreate(null), {
26+
const protocolHandlers = {
27+
'__proto__': null,
2928
'data:': getDataProtocolModuleFormat,
3029
'file:': getFileProtocolModuleFormat,
3130
'http:': getHttpProtocolModuleFormat,
3231
'https:': getHttpProtocolModuleFormat,
3332
'node:'() { return 'builtin'; },
34-
});
33+
};
3534

3635
/**
3736
* @param {URL} parsed

lib/internal/modules/esm/loader.js

+68-69
Original file line numberDiff line numberDiff line change
@@ -179,39 +179,38 @@ function nextHookFactory(chain, meta, { validateArgs, validateOutput }) {
179179
* the main module and everything in its dependency graph.
180180
*/
181181
class ESMLoader {
182-
/**
183-
* Prior to ESM loading. These are called once before any modules are started.
184-
* @private
185-
* @property {KeyedHook[]} globalPreloaders Last-in-first-out
186-
* list of preload hooks.
187-
*/
188-
#globalPreloaders = [];
189-
190-
/**
191-
* Phase 2 of 2 in ESM loading.
192-
* @private
193-
* @property {KeyedHook[]} loaders Last-in-first-out
194-
* collection of loader hooks.
195-
*/
196-
#loaders = [
197-
{
198-
fn: defaultLoad,
199-
url: 'node:internal/modules/esm/load',
200-
},
201-
];
202-
203-
/**
204-
* Phase 1 of 2 in ESM loading.
205-
* @private
206-
* @property {KeyedHook[]} resolvers Last-in-first-out
207-
* collection of resolver hooks.
208-
*/
209-
#resolvers = [
210-
{
211-
fn: defaultResolve,
212-
url: 'node:internal/modules/esm/resolve',
213-
},
214-
];
182+
#hooks = {
183+
/**
184+
* Prior to ESM loading. These are called once before any modules are started.
185+
* @private
186+
* @property {KeyedHook[]} globalPreload Last-in-first-out list of preload hooks.
187+
*/
188+
globalPreload: [],
189+
190+
/**
191+
* Phase 2 of 2 in ESM loading (phase 1 is below).
192+
* @private
193+
* @property {KeyedHook[]} load Last-in-first-out collection of loader hooks.
194+
*/
195+
load: [
196+
{
197+
fn: defaultLoad,
198+
url: 'node:internal/modules/esm/load',
199+
},
200+
],
201+
202+
/**
203+
* Phase 1 of 2 in ESM loading.
204+
* @private
205+
* @property {KeyedHook[]} resolve Last-in-first-out collection of resolve hooks.
206+
*/
207+
resolve: [
208+
{
209+
fn: defaultResolve,
210+
url: 'node:internal/modules/esm/resolve',
211+
},
212+
],
213+
};
215214

216215
#importMetaInitializer = initializeImportMeta;
217216

@@ -305,13 +304,13 @@ class ESMLoader {
305304
);
306305

307306
if (globalPreload) {
308-
acceptedHooks.globalPreloader = globalPreload;
307+
acceptedHooks.globalPreload = globalPreload;
309308
}
310309
if (resolve) {
311-
acceptedHooks.resolver = resolve;
310+
acceptedHooks.resolve = resolve;
312311
}
313312
if (load) {
314-
acceptedHooks.loader = load;
313+
acceptedHooks.load = load;
315314
}
316315

317316
return acceptedHooks;
@@ -333,34 +332,34 @@ class ESMLoader {
333332
url,
334333
} = customLoaders[i];
335334
const {
336-
globalPreloader,
337-
resolver,
338-
loader,
335+
globalPreload,
336+
resolve,
337+
load,
339338
} = ESMLoader.pluckHooks(exports);
340339

341-
if (globalPreloader) {
340+
if (globalPreload) {
342341
ArrayPrototypePush(
343-
this.#globalPreloaders,
342+
this.#hooks.globalPreload,
344343
{
345-
fn: globalPreloader,
344+
fn: globalPreload,
346345
url,
347346
},
348347
);
349348
}
350-
if (resolver) {
349+
if (resolve) {
351350
ArrayPrototypePush(
352-
this.#resolvers,
351+
this.#hooks.resolve,
353352
{
354-
fn: resolver,
353+
fn: resolve,
355354
url,
356355
},
357356
);
358357
}
359-
if (loader) {
358+
if (load) {
360359
ArrayPrototypePush(
361-
this.#loaders,
360+
this.#hooks.load,
362361
{
363-
fn: loader,
362+
fn: load,
364363
url,
365364
},
366365
);
@@ -411,14 +410,14 @@ class ESMLoader {
411410
async getModuleJob(specifier, parentURL, importAssertions) {
412411
let importAssertionsForResolve;
413412

414-
// By default, `this.#loaders` contains just the Node default load hook
415-
if (this.#loaders.length !== 1) {
413+
// By default, `this.#hooks.load` contains just the Node default load hook
414+
if (this.#hooks.load.length !== 1) {
416415
// We can skip cloning if there are no user-provided loaders because
417416
// the Node.js default resolve hook does not use import assertions.
418-
importAssertionsForResolve = ObjectAssign(
419-
ObjectCreate(null),
420-
importAssertions,
421-
);
417+
importAssertionsForResolve = {
418+
__proto__: null,
419+
...importAssertions,
420+
};
422421
}
423422

424423
const { format, url } =
@@ -533,11 +532,11 @@ class ESMLoader {
533532
if (!wasArr) { return namespaces[0]; } // We can skip the pairing below
534533

535534
for (let i = 0; i < count; i++) {
536-
const namespace = ObjectCreate(null);
537-
namespace.url = specifiers[i];
538-
namespace.exports = namespaces[i];
539-
540-
namespaces[i] = namespace;
535+
namespaces[i] = {
536+
__proto__: null,
537+
url: specifiers[i],
538+
exports: namespaces[i],
539+
};
541540
}
542541

543542
return namespaces;
@@ -555,7 +554,7 @@ class ESMLoader {
555554
* @returns {{ format: ModuleFormat, source: ModuleSource }}
556555
*/
557556
async load(url, context = {}) {
558-
const chain = this.#loaders;
557+
const chain = this.#hooks.load;
559558
const meta = {
560559
chainFinished: null,
561560
context,
@@ -684,7 +683,7 @@ class ESMLoader {
684683
}
685684

686685
preload() {
687-
for (let i = this.#globalPreloaders.length - 1; i >= 0; i--) {
686+
for (let i = this.#hooks.globalPreload.length - 1; i >= 0; i--) {
688687
const channel = new MessageChannel();
689688
const {
690689
port1: insidePreload,
@@ -695,19 +694,19 @@ class ESMLoader {
695694
insideLoader.unref();
696695

697696
const {
698-
fn: preloader,
697+
fn: preload,
699698
url: specifier,
700-
} = this.#globalPreloaders[i];
699+
} = this.#hooks.globalPreload[i];
701700

702-
const preload = preloader({
701+
const preloaded = preload({
703702
port: insideLoader,
704703
});
705704

706-
if (preload == null) { return; }
705+
if (preloaded == null) { return; }
707706

708707
const hookErrIdentifier = `${specifier} globalPreload`;
709708

710-
if (typeof preload !== 'string') { // [2]
709+
if (typeof preloaded !== 'string') { // [2]
711710
throw new ERR_INVALID_RETURN_VALUE(
712711
'a string',
713712
hookErrIdentifier,
@@ -716,7 +715,7 @@ class ESMLoader {
716715
}
717716
const { compileFunction } = require('vm');
718717
const preloadInit = compileFunction(
719-
preload,
718+
preloaded,
720719
['getBuiltin', 'port', 'setImportMetaCallback'],
721720
{
722721
filename: '<preload>',
@@ -789,7 +788,7 @@ class ESMLoader {
789788
async resolve(
790789
originalSpecifier,
791790
parentURL,
792-
importAssertions = ObjectCreate(null)
791+
importAssertions = ObjectCreate(null),
793792
) {
794793
const isMain = parentURL === undefined;
795794

@@ -804,7 +803,7 @@ class ESMLoader {
804803
parentURL,
805804
);
806805
}
807-
const chain = this.#resolvers;
806+
const chain = this.#hooks.resolve;
808807
const context = {
809808
conditions: DEFAULT_CONDITIONS,
810809
importAssertions,

test/es-module/test-esm-loader-hooks.mjs

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const { ESMLoader } = esmLoaderModule;
1212
const esmLoader = new ESMLoader();
1313

1414
const originalSpecifier = 'foo/bar';
15-
const importAssertions = Object.assign(
16-
Object.create(null),
17-
{ type: 'json' },
18-
);
15+
const importAssertions = {
16+
__proto__: null,
17+
type: 'json',
18+
};
1919
const parentURL = 'file:///entrypoint.js';
2020
const resolvedURL = 'file:///foo/bar.js';
2121
const suggestedFormat = 'test';

0 commit comments

Comments
 (0)