Skip to content

Commit 42a91e3

Browse files
JakobJingleheimerjuanarbol
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 fe91711 commit 42a91e3

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,7 +1,5 @@
11
'use strict';
22
const {
3-
ObjectAssign,
4-
ObjectCreate,
53
ObjectPrototypeHasOwnProperty,
64
PromisePrototypeThen,
75
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
function getDataProtocolModuleFormat(parsed) {
3736
const { 1: mime } = RegExpPrototypeExec(

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 } =
@@ -529,11 +528,11 @@ class ESMLoader {
529528
if (!wasArr) { return namespaces[0]; } // We can skip the pairing below
530529

531530
for (let i = 0; i < count; i++) {
532-
const namespace = ObjectCreate(null);
533-
namespace.url = specifiers[i];
534-
namespace.exports = namespaces[i];
535-
536-
namespaces[i] = namespace;
531+
namespaces[i] = {
532+
__proto__: null,
533+
url: specifiers[i],
534+
exports: namespaces[i],
535+
};
537536
}
538537

539538
return namespaces;
@@ -551,7 +550,7 @@ class ESMLoader {
551550
* @returns {{ format: ModuleFormat, source: ModuleSource }}
552551
*/
553552
async load(url, context = {}) {
554-
const chain = this.#loaders;
553+
const chain = this.#hooks.load;
555554
const meta = {
556555
chainFinished: null,
557556
context,
@@ -680,7 +679,7 @@ class ESMLoader {
680679
}
681680

682681
preload() {
683-
for (let i = this.#globalPreloaders.length - 1; i >= 0; i--) {
682+
for (let i = this.#hooks.globalPreload.length - 1; i >= 0; i--) {
684683
const channel = new MessageChannel();
685684
const {
686685
port1: insidePreload,
@@ -691,19 +690,19 @@ class ESMLoader {
691690
insideLoader.unref();
692691

693692
const {
694-
fn: preloader,
693+
fn: preload,
695694
url: specifier,
696-
} = this.#globalPreloaders[i];
695+
} = this.#hooks.globalPreload[i];
697696

698-
const preload = preloader({
697+
const preloaded = preload({
699698
port: insideLoader,
700699
});
701700

702-
if (preload == null) { return; }
701+
if (preloaded == null) { return; }
703702

704703
const hookErrIdentifier = `${specifier} globalPreload`;
705704

706-
if (typeof preload !== 'string') { // [2]
705+
if (typeof preloaded !== 'string') { // [2]
707706
throw new ERR_INVALID_RETURN_VALUE(
708707
'a string',
709708
hookErrIdentifier,
@@ -712,7 +711,7 @@ class ESMLoader {
712711
}
713712
const { compileFunction } = require('vm');
714713
const preloadInit = compileFunction(
715-
preload,
714+
preloaded,
716715
['getBuiltin', 'port', 'setImportMetaCallback'],
717716
{
718717
filename: '<preload>',
@@ -785,7 +784,7 @@ class ESMLoader {
785784
async resolve(
786785
originalSpecifier,
787786
parentURL,
788-
importAssertions = ObjectCreate(null)
787+
importAssertions = ObjectCreate(null),
789788
) {
790789
const isMain = parentURL === undefined;
791790

@@ -800,7 +799,7 @@ class ESMLoader {
800799
parentURL,
801800
);
802801
}
803-
const chain = this.#resolvers;
802+
const chain = this.#hooks.resolve;
804803
const context = {
805804
conditions: DEFAULT_CONDITIONS,
806805
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)