Skip to content

Commit 9e7f166

Browse files
aduh95targos
authored andcommitted
module: refactor to use more primordials
PR-URL: #36024 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent 24d4d63 commit 9e7f166

File tree

3 files changed

+83
-54
lines changed

3 files changed

+83
-54
lines changed

lib/internal/modules/cjs/helpers.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
'use strict';
22

33
const {
4+
ArrayPrototypeForEach,
45
ArrayPrototypeJoin,
56
ObjectDefineProperty,
67
ObjectPrototypeHasOwnProperty,
78
SafeMap,
89
SafeSet,
10+
StringPrototypeCharCodeAt,
11+
StringPrototypeIncludes,
12+
StringPrototypeSlice,
13+
StringPrototypeStartsWith,
914
} = primordials;
1015
const {
1116
ERR_MANIFEST_DEPENDENCY_MISSING,
@@ -15,8 +20,7 @@ const { NativeModule } = require('internal/bootstrap/loaders');
1520

1621
const { validateString } = require('internal/validators');
1722
const path = require('path');
18-
const { pathToFileURL, fileURLToPath } = require('internal/url');
19-
const { URL } = require('url');
23+
const { pathToFileURL, fileURLToPath, URL } = require('internal/url');
2024

2125
const { getOptionValue } = require('internal/options');
2226
const userConditions = getOptionValue('--conditions');
@@ -119,20 +123,20 @@ function makeRequireFunction(mod, redirects) {
119123
* translates it to FEFF, the UTF-16 BOM.
120124
*/
121125
function stripBOM(content) {
122-
if (content.charCodeAt(0) === 0xFEFF) {
123-
content = content.slice(1);
126+
if (StringPrototypeCharCodeAt(content) === 0xFEFF) {
127+
content = StringPrototypeSlice(content, 1);
124128
}
125129
return content;
126130
}
127131

128132
function addBuiltinLibsToObject(object) {
129133
// Make built-in modules available directly (loaded lazily).
130134
const { builtinModules } = require('internal/modules/cjs/loader').Module;
131-
builtinModules.forEach((name) => {
135+
ArrayPrototypeForEach(builtinModules, (name) => {
132136
// Neither add underscored modules, nor ones that contain slashes (e.g.,
133137
// 'fs/promises') or ones that are already defined.
134-
if (name.startsWith('_') ||
135-
name.includes('/') ||
138+
if (StringPrototypeStartsWith(name, '_') ||
139+
StringPrototypeIncludes(name, '/') ||
136140
ObjectPrototypeHasOwnProperty(object, name)) {
137141
return;
138142
}

lib/internal/modules/cjs/loader.js

+65-44
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,17 @@
2323

2424
const {
2525
ArrayIsArray,
26+
ArrayPrototypeConcat,
27+
ArrayPrototypeFilter,
28+
ArrayPrototypeIncludes,
29+
ArrayPrototypeIndexOf,
2630
ArrayPrototypeJoin,
31+
ArrayPrototypePush,
32+
ArrayPrototypeSlice,
33+
ArrayPrototypeSplice,
34+
Boolean,
2735
Error,
2836
JSONParse,
29-
Map,
3037
ObjectCreate,
3138
ObjectDefineProperty,
3239
ObjectFreeze,
@@ -36,16 +43,20 @@ const {
3643
ObjectPrototype,
3744
ObjectPrototypeHasOwnProperty,
3845
ObjectSetPrototypeOf,
46+
ReflectApply,
3947
ReflectSet,
4048
RegExpPrototypeTest,
4149
SafeMap,
4250
SafeWeakMap,
4351
String,
52+
StringPrototypeCharAt,
53+
StringPrototypeCharCodeAt,
4454
StringPrototypeEndsWith,
4555
StringPrototypeLastIndexOf,
4656
StringPrototypeIndexOf,
4757
StringPrototypeMatch,
4858
StringPrototypeSlice,
59+
StringPrototypeSplit,
4960
StringPrototypeStartsWith,
5061
} = primordials;
5162

@@ -144,8 +155,8 @@ function stat(filename) {
144155

145156
function updateChildren(parent, child, scan) {
146157
const children = parent && parent.children;
147-
if (children && !(scan && children.includes(child)))
148-
children.push(child);
158+
if (children && !(scan && ArrayPrototypeIncludes(children, child)))
159+
ArrayPrototypePush(children, child);
149160
}
150161

151162
function Module(id = '', parent) {
@@ -162,7 +173,7 @@ function Module(id = '', parent) {
162173
const builtinModules = [];
163174
for (const [id, mod] of NativeModule.map) {
164175
if (mod.canBeRequiredByUsers) {
165-
builtinModules.push(id);
176+
ArrayPrototypePush(builtinModules, id);
166177
}
167178
}
168179

@@ -331,7 +342,7 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
331342
// In order to minimize unnecessary lstat() calls,
332343
// this cache is a list of known-real paths.
333344
// Set to an empty Map to reset.
334-
const realpathCache = new Map();
345+
const realpathCache = new SafeMap();
335346

336347
// Check if the file exists and is not a directory
337348
// if using --preserve-symlinks and isMain is false,
@@ -371,10 +382,10 @@ function findLongestRegisteredExtension(filename) {
371382
let currentExtension;
372383
let index;
373384
let startIndex = 0;
374-
while ((index = name.indexOf('.', startIndex)) !== -1) {
385+
while ((index = StringPrototypeIndexOf(name, '.', startIndex)) !== -1) {
375386
startIndex = index + 1;
376387
if (index === 0) continue; // Skip dotfiles like .gitignore
377-
currentExtension = name.slice(index);
388+
currentExtension = StringPrototypeSlice(name, index);
378389
if (Module._extensions[currentExtension]) return currentExtension;
379390
}
380391
return '.js';
@@ -455,15 +466,15 @@ Module._findPath = function(request, paths, isMain) {
455466
return false;
456467
}
457468

458-
const cacheKey = request + '\x00' +
459-
(paths.length === 1 ? paths[0] : paths.join('\x00'));
469+
const cacheKey = request + '\x00' + ArrayPrototypeJoin(paths, '\x00');
460470
const entry = Module._pathCache[cacheKey];
461471
if (entry)
462472
return entry;
463473

464474
let exts;
465475
let trailingSlash = request.length > 0 &&
466-
request.charCodeAt(request.length - 1) === CHAR_FORWARD_SLASH;
476+
StringPrototypeCharCodeAt(request, request.length - 1) ===
477+
CHAR_FORWARD_SLASH;
467478
if (!trailingSlash) {
468479
trailingSlash = RegExpPrototypeTest(trailingSlashRegex, request);
469480
}
@@ -546,13 +557,14 @@ if (isWindows) {
546557

547558
// return root node_modules when path is 'D:\\'.
548559
// path.resolve will make sure from.length >=3 in Windows.
549-
if (from.charCodeAt(from.length - 1) === CHAR_BACKWARD_SLASH &&
550-
from.charCodeAt(from.length - 2) === CHAR_COLON)
560+
if (StringPrototypeCharCodeAt(from, from.length - 1) ===
561+
CHAR_BACKWARD_SLASH &&
562+
StringPrototypeCharCodeAt(from, from.length - 2) === CHAR_COLON)
551563
return [from + 'node_modules'];
552564

553565
const paths = [];
554566
for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) {
555-
const code = from.charCodeAt(i);
567+
const code = StringPrototypeCharCodeAt(from, i);
556568
// The path segment separator check ('\' and '/') was used to get
557569
// node_modules path for every path segment.
558570
// Use colon as an extra condition since we can get node_modules
@@ -562,7 +574,10 @@ if (isWindows) {
562574
code === CHAR_FORWARD_SLASH ||
563575
code === CHAR_COLON) {
564576
if (p !== nmLen)
565-
paths.push(from.slice(0, last) + '\\node_modules');
577+
ArrayPrototypePush(
578+
paths,
579+
StringPrototypeSlice(from, 0, last) + '\\node_modules'
580+
);
566581
last = i;
567582
p = 0;
568583
} else if (p !== -1) {
@@ -591,10 +606,13 @@ if (isWindows) {
591606
// that works on both Windows and Posix is non-trivial.
592607
const paths = [];
593608
for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) {
594-
const code = from.charCodeAt(i);
609+
const code = StringPrototypeCharCodeAt(from, i);
595610
if (code === CHAR_FORWARD_SLASH) {
596611
if (p !== nmLen)
597-
paths.push(from.slice(0, last) + '/node_modules');
612+
ArrayPrototypePush(
613+
paths,
614+
StringPrototypeSlice(from, 0, last) + '/node_modules'
615+
);
598616
last = i;
599617
p = 0;
600618
} else if (p !== -1) {
@@ -607,7 +625,7 @@ if (isWindows) {
607625
}
608626

609627
// Append /node_modules to handle root paths.
610-
paths.push('/node_modules');
628+
ArrayPrototypePush(paths, '/node_modules');
611629

612630
return paths;
613631
};
@@ -620,15 +638,15 @@ Module._resolveLookupPaths = function(request, parent) {
620638
}
621639

622640
// Check for node modules paths.
623-
if (request.charAt(0) !== '.' ||
641+
if (StringPrototypeCharAt(request, 0) !== '.' ||
624642
(request.length > 1 &&
625-
request.charAt(1) !== '.' &&
626-
request.charAt(1) !== '/' &&
627-
(!isWindows || request.charAt(1) !== '\\'))) {
643+
StringPrototypeCharAt(request, 1) !== '.' &&
644+
StringPrototypeCharAt(request, 1) !== '/' &&
645+
(!isWindows || StringPrototypeCharAt(request, 1) !== '\\'))) {
628646

629647
let paths = modulePaths;
630648
if (parent != null && parent.paths && parent.paths.length) {
631-
paths = parent.paths.concat(paths);
649+
paths = ArrayPrototypeConcat(parent.paths, paths);
632650
}
633651

634652
debug('looking for %j in %j', request, paths);
@@ -778,9 +796,9 @@ Module._load = function(request, parent, isMain) {
778796
delete relativeResolveCache[relResolveCacheIdentifier];
779797
const children = parent && parent.children;
780798
if (ArrayIsArray(children)) {
781-
const index = children.indexOf(module);
799+
const index = ArrayPrototypeIndexOf(children, module);
782800
if (index !== -1) {
783-
children.splice(index, 1);
801+
ArrayPrototypeSplice(children, index, 1);
784802
}
785803
}
786804
}
@@ -804,10 +822,10 @@ Module._resolveFilename = function(request, parent, isMain, options) {
804822

805823
if (typeof options === 'object' && options !== null) {
806824
if (ArrayIsArray(options.paths)) {
807-
const isRelative = request.startsWith('./') ||
808-
request.startsWith('../') ||
809-
((isWindows && request.startsWith('.\\')) ||
810-
request.startsWith('..\\'));
825+
const isRelative = StringPrototypeStartsWith(request, './') ||
826+
StringPrototypeStartsWith(request, '../') ||
827+
((isWindows && StringPrototypeStartsWith(request, '.\\')) ||
828+
StringPrototypeStartsWith(request, '..\\'));
811829

812830
if (isRelative) {
813831
paths = options.paths;
@@ -822,8 +840,8 @@ Module._resolveFilename = function(request, parent, isMain, options) {
822840
const lookupPaths = Module._resolveLookupPaths(request, fakeParent);
823841

824842
for (let j = 0; j < lookupPaths.length; j++) {
825-
if (!paths.includes(lookupPaths[j]))
826-
paths.push(lookupPaths[j]);
843+
if (!ArrayPrototypeIncludes(paths, lookupPaths[j]))
844+
ArrayPrototypePush(paths, lookupPaths[j]);
827845
}
828846
}
829847
}
@@ -872,11 +890,12 @@ Module._resolveFilename = function(request, parent, isMain, options) {
872890
for (let cursor = parent;
873891
cursor;
874892
cursor = cursor.parent) {
875-
requireStack.push(cursor.filename || cursor.id);
893+
ArrayPrototypePush(requireStack, cursor.filename || cursor.id);
876894
}
877895
let message = `Cannot find module '${request}'`;
878896
if (requireStack.length > 0) {
879-
message = message + '\nRequire stack:\n- ' + requireStack.join('\n- ');
897+
message = message + '\nRequire stack:\n- ' +
898+
ArrayPrototypeJoin(requireStack, '\n- ');
880899
}
881900
// eslint-disable-next-line no-restricted-syntax
882901
const err = new Error(message);
@@ -887,7 +906,7 @@ Module._resolveFilename = function(request, parent, isMain, options) {
887906

888907
function finalizeEsmResolution(match, request, parentPath, pkgPath) {
889908
const { resolved, exact } = match;
890-
if (StringPrototypeMatch(resolved, encodedSepRegEx))
909+
if (RegExpPrototypeTest(encodedSepRegEx, resolved))
891910
throw new ERR_INVALID_MODULE_SPECIFIER(
892911
resolved, 'must not include encoded "/" or "\\" characters', parentPath);
893912
const filename = fileURLToPath(resolved);
@@ -924,9 +943,9 @@ Module.prototype.load = function(filename) {
924943

925944
const extension = findLongestRegisteredExtension(filename);
926945
// allow .mjs to be overridden
927-
if (filename.endsWith('.mjs') && !Module._extensions['.mjs']) {
946+
if (StringPrototypeEndsWith(filename, '.mjs') && !Module._extensions['.mjs'])
928947
throw new ERR_REQUIRE_ESM(filename);
929-
}
948+
930949
Module._extensions[extension](this, filename);
931950
this.loaded = true;
932951

@@ -1057,13 +1076,13 @@ Module.prototype._compile = function(content, filename) {
10571076
const exports = this.exports;
10581077
const thisValue = exports;
10591078
const module = this;
1060-
if (requireDepth === 0) statCache = new Map();
1079+
if (requireDepth === 0) statCache = new SafeMap();
10611080
if (inspectorWrapper) {
10621081
result = inspectorWrapper(compiledWrapper, thisValue, exports,
10631082
require, module, filename, dirname);
10641083
} else {
1065-
result = compiledWrapper.call(thisValue, exports, require, module,
1066-
filename, dirname);
1084+
result = ReflectApply(compiledWrapper, thisValue,
1085+
[exports, require, module, filename, dirname]);
10671086
}
10681087
hasLoadedAnyUserCJSModule = true;
10691088
if (requireDepth === 0) statCache = null;
@@ -1072,7 +1091,7 @@ Module.prototype._compile = function(content, filename) {
10721091

10731092
// Native extension for .js
10741093
Module._extensions['.js'] = function(module, filename) {
1075-
if (filename.endsWith('.js')) {
1094+
if (StringPrototypeEndsWith(filename, '.js')) {
10761095
const pkg = readPackageScope(filename);
10771096
// Function require shouldn't be used in ES modules.
10781097
if (pkg && pkg.data && pkg.data.type === 'module') {
@@ -1127,7 +1146,8 @@ Module._extensions['.node'] = function(module, filename) {
11271146
function createRequireFromPath(filename) {
11281147
// Allow a directory to be passed as the filename
11291148
const trailingSlash =
1130-
filename.endsWith('/') || (isWindows && filename.endsWith('\\'));
1149+
StringPrototypeEndsWith(filename, '/') ||
1150+
(isWindows && StringPrototypeEndsWith(filename, '\\'));
11311151

11321152
const proxyPath = trailingSlash ?
11331153
path.join(filename, 'noop.js') :
@@ -1189,15 +1209,16 @@ Module._initPaths = function() {
11891209
}
11901210

11911211
if (nodePath) {
1192-
paths = nodePath.split(path.delimiter).filter(function pathsFilterCB(path) {
1193-
return !!path;
1194-
}).concat(paths);
1212+
paths = ArrayPrototypeConcat(ArrayPrototypeFilter(
1213+
StringPrototypeSplit(nodePath, path.delimiter),
1214+
Boolean
1215+
), paths);
11951216
}
11961217

11971218
modulePaths = paths;
11981219

11991220
// Clone as a shallow copy, for introspection.
1200-
Module.globalPaths = modulePaths.slice(0);
1221+
Module.globalPaths = ArrayPrototypeSlice(modulePaths);
12011222
};
12021223

12031224
Module._preloadModules = function(requests) {

lib/internal/modules/run_main.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
'use strict';
22

3+
const {
4+
PromisePrototypeFinally,
5+
StringPrototypeEndsWith,
6+
} = primordials;
37
const CJSLoader = require('internal/modules/cjs/loader');
48
const { Module, toRealPath, readPackageScope } = CJSLoader;
59
const { getOptionValue } = require('internal/options');
@@ -29,9 +33,9 @@ function shouldUseESMLoader(mainPath) {
2933
if (esModuleSpecifierResolution === 'node')
3034
return true;
3135
// Determine the module format of the main
32-
if (mainPath && mainPath.endsWith('.mjs'))
36+
if (mainPath && StringPrototypeEndsWith(mainPath, '.mjs'))
3337
return true;
34-
if (!mainPath || mainPath.endsWith('.cjs'))
38+
if (!mainPath || StringPrototypeEndsWith(mainPath, '.cjs'))
3539
return false;
3640
const pkg = readPackageScope(mainPath);
3741
return pkg && pkg.data.type === 'module';
@@ -56,7 +60,7 @@ function handleMainPromise(promise) {
5660
process.exitCode = 13;
5761
}
5862
process.on('exit', handler);
59-
return promise.finally(() => process.off('exit', handler));
63+
return PromisePrototypeFinally(promise, () => process.off('exit', handler));
6064
}
6165

6266
// For backwards compatibility, we have to run a bunch of

0 commit comments

Comments
 (0)