Skip to content

Commit 7a37590

Browse files
aduh95danielleadams
authored andcommitted
module: refactor to use more primordials
PR-URL: #36024 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
1 parent 7ef9c70 commit 7a37590

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

@@ -142,8 +153,8 @@ function stat(filename) {
142153

143154
function updateChildren(parent, child, scan) {
144155
const children = parent && parent.children;
145-
if (children && !(scan && children.includes(child)))
146-
children.push(child);
156+
if (children && !(scan && ArrayPrototypeIncludes(children, child)))
157+
ArrayPrototypePush(children, child);
147158
}
148159

149160
const moduleParentCache = new SafeWeakMap();
@@ -161,7 +172,7 @@ function Module(id = '', parent) {
161172
const builtinModules = [];
162173
for (const [id, mod] of NativeModule.map) {
163174
if (mod.canBeRequiredByUsers) {
164-
builtinModules.push(id);
175+
ArrayPrototypePush(builtinModules, id);
165176
}
166177
}
167178

@@ -349,7 +360,7 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
349360
// In order to minimize unnecessary lstat() calls,
350361
// this cache is a list of known-real paths.
351362
// Set to an empty Map to reset.
352-
const realpathCache = new Map();
363+
const realpathCache = new SafeMap();
353364

354365
// Check if the file exists and is not a directory
355366
// if using --preserve-symlinks and isMain is false,
@@ -389,10 +400,10 @@ function findLongestRegisteredExtension(filename) {
389400
let currentExtension;
390401
let index;
391402
let startIndex = 0;
392-
while ((index = name.indexOf('.', startIndex)) !== -1) {
403+
while ((index = StringPrototypeIndexOf(name, '.', startIndex)) !== -1) {
393404
startIndex = index + 1;
394405
if (index === 0) continue; // Skip dotfiles like .gitignore
395-
currentExtension = name.slice(index);
406+
currentExtension = StringPrototypeSlice(name, index);
396407
if (Module._extensions[currentExtension]) return currentExtension;
397408
}
398409
return '.js';
@@ -473,15 +484,15 @@ Module._findPath = function(request, paths, isMain) {
473484
return false;
474485
}
475486

476-
const cacheKey = request + '\x00' +
477-
(paths.length === 1 ? paths[0] : paths.join('\x00'));
487+
const cacheKey = request + '\x00' + ArrayPrototypeJoin(paths, '\x00');
478488
const entry = Module._pathCache[cacheKey];
479489
if (entry)
480490
return entry;
481491

482492
let exts;
483493
let trailingSlash = request.length > 0 &&
484-
request.charCodeAt(request.length - 1) === CHAR_FORWARD_SLASH;
494+
StringPrototypeCharCodeAt(request, request.length - 1) ===
495+
CHAR_FORWARD_SLASH;
485496
if (!trailingSlash) {
486497
trailingSlash = RegExpPrototypeTest(trailingSlashRegex, request);
487498
}
@@ -564,13 +575,14 @@ if (isWindows) {
564575

565576
// return root node_modules when path is 'D:\\'.
566577
// path.resolve will make sure from.length >=3 in Windows.
567-
if (from.charCodeAt(from.length - 1) === CHAR_BACKWARD_SLASH &&
568-
from.charCodeAt(from.length - 2) === CHAR_COLON)
578+
if (StringPrototypeCharCodeAt(from, from.length - 1) ===
579+
CHAR_BACKWARD_SLASH &&
580+
StringPrototypeCharCodeAt(from, from.length - 2) === CHAR_COLON)
569581
return [from + 'node_modules'];
570582

571583
const paths = [];
572584
for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) {
573-
const code = from.charCodeAt(i);
585+
const code = StringPrototypeCharCodeAt(from, i);
574586
// The path segment separator check ('\' and '/') was used to get
575587
// node_modules path for every path segment.
576588
// Use colon as an extra condition since we can get node_modules
@@ -580,7 +592,10 @@ if (isWindows) {
580592
code === CHAR_FORWARD_SLASH ||
581593
code === CHAR_COLON) {
582594
if (p !== nmLen)
583-
paths.push(from.slice(0, last) + '\\node_modules');
595+
ArrayPrototypePush(
596+
paths,
597+
StringPrototypeSlice(from, 0, last) + '\\node_modules'
598+
);
584599
last = i;
585600
p = 0;
586601
} else if (p !== -1) {
@@ -609,10 +624,13 @@ if (isWindows) {
609624
// that works on both Windows and Posix is non-trivial.
610625
const paths = [];
611626
for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) {
612-
const code = from.charCodeAt(i);
627+
const code = StringPrototypeCharCodeAt(from, i);
613628
if (code === CHAR_FORWARD_SLASH) {
614629
if (p !== nmLen)
615-
paths.push(from.slice(0, last) + '/node_modules');
630+
ArrayPrototypePush(
631+
paths,
632+
StringPrototypeSlice(from, 0, last) + '/node_modules'
633+
);
616634
last = i;
617635
p = 0;
618636
} else if (p !== -1) {
@@ -625,7 +643,7 @@ if (isWindows) {
625643
}
626644

627645
// Append /node_modules to handle root paths.
628-
paths.push('/node_modules');
646+
ArrayPrototypePush(paths, '/node_modules');
629647

630648
return paths;
631649
};
@@ -638,15 +656,15 @@ Module._resolveLookupPaths = function(request, parent) {
638656
}
639657

640658
// Check for node modules paths.
641-
if (request.charAt(0) !== '.' ||
659+
if (StringPrototypeCharAt(request, 0) !== '.' ||
642660
(request.length > 1 &&
643-
request.charAt(1) !== '.' &&
644-
request.charAt(1) !== '/' &&
645-
(!isWindows || request.charAt(1) !== '\\'))) {
661+
StringPrototypeCharAt(request, 1) !== '.' &&
662+
StringPrototypeCharAt(request, 1) !== '/' &&
663+
(!isWindows || StringPrototypeCharAt(request, 1) !== '\\'))) {
646664

647665
let paths = modulePaths;
648666
if (parent != null && parent.paths && parent.paths.length) {
649-
paths = parent.paths.concat(paths);
667+
paths = ArrayPrototypeConcat(parent.paths, paths);
650668
}
651669

652670
debug('looking for %j in %j', request, paths);
@@ -796,9 +814,9 @@ Module._load = function(request, parent, isMain) {
796814
delete relativeResolveCache[relResolveCacheIdentifier];
797815
const children = parent && parent.children;
798816
if (ArrayIsArray(children)) {
799-
const index = children.indexOf(module);
817+
const index = ArrayPrototypeIndexOf(children, module);
800818
if (index !== -1) {
801-
children.splice(index, 1);
819+
ArrayPrototypeSplice(children, index, 1);
802820
}
803821
}
804822
}
@@ -822,10 +840,10 @@ Module._resolveFilename = function(request, parent, isMain, options) {
822840

823841
if (typeof options === 'object' && options !== null) {
824842
if (ArrayIsArray(options.paths)) {
825-
const isRelative = request.startsWith('./') ||
826-
request.startsWith('../') ||
827-
((isWindows && request.startsWith('.\\')) ||
828-
request.startsWith('..\\'));
843+
const isRelative = StringPrototypeStartsWith(request, './') ||
844+
StringPrototypeStartsWith(request, '../') ||
845+
((isWindows && StringPrototypeStartsWith(request, '.\\')) ||
846+
StringPrototypeStartsWith(request, '..\\'));
829847

830848
if (isRelative) {
831849
paths = options.paths;
@@ -840,8 +858,8 @@ Module._resolveFilename = function(request, parent, isMain, options) {
840858
const lookupPaths = Module._resolveLookupPaths(request, fakeParent);
841859

842860
for (let j = 0; j < lookupPaths.length; j++) {
843-
if (!paths.includes(lookupPaths[j]))
844-
paths.push(lookupPaths[j]);
861+
if (!ArrayPrototypeIncludes(paths, lookupPaths[j]))
862+
ArrayPrototypePush(paths, lookupPaths[j]);
845863
}
846864
}
847865
}
@@ -890,11 +908,12 @@ Module._resolveFilename = function(request, parent, isMain, options) {
890908
for (let cursor = parent;
891909
cursor;
892910
cursor = moduleParentCache.get(cursor)) {
893-
requireStack.push(cursor.filename || cursor.id);
911+
ArrayPrototypePush(requireStack, cursor.filename || cursor.id);
894912
}
895913
let message = `Cannot find module '${request}'`;
896914
if (requireStack.length > 0) {
897-
message = message + '\nRequire stack:\n- ' + requireStack.join('\n- ');
915+
message = message + '\nRequire stack:\n- ' +
916+
ArrayPrototypeJoin(requireStack, '\n- ');
898917
}
899918
// eslint-disable-next-line no-restricted-syntax
900919
const err = new Error(message);
@@ -905,7 +924,7 @@ Module._resolveFilename = function(request, parent, isMain, options) {
905924

906925
function finalizeEsmResolution(match, request, parentPath, pkgPath) {
907926
const { resolved, exact } = match;
908-
if (StringPrototypeMatch(resolved, encodedSepRegEx))
927+
if (RegExpPrototypeTest(encodedSepRegEx, resolved))
909928
throw new ERR_INVALID_MODULE_SPECIFIER(
910929
resolved, 'must not include encoded "/" or "\\" characters', parentPath);
911930
const filename = fileURLToPath(resolved);
@@ -942,9 +961,9 @@ Module.prototype.load = function(filename) {
942961

943962
const extension = findLongestRegisteredExtension(filename);
944963
// allow .mjs to be overridden
945-
if (filename.endsWith('.mjs') && !Module._extensions['.mjs']) {
964+
if (StringPrototypeEndsWith(filename, '.mjs') && !Module._extensions['.mjs'])
946965
throw new ERR_REQUIRE_ESM(filename);
947-
}
966+
948967
Module._extensions[extension](this, filename);
949968
this.loaded = true;
950969

@@ -1075,13 +1094,13 @@ Module.prototype._compile = function(content, filename) {
10751094
const exports = this.exports;
10761095
const thisValue = exports;
10771096
const module = this;
1078-
if (requireDepth === 0) statCache = new Map();
1097+
if (requireDepth === 0) statCache = new SafeMap();
10791098
if (inspectorWrapper) {
10801099
result = inspectorWrapper(compiledWrapper, thisValue, exports,
10811100
require, module, filename, dirname);
10821101
} else {
1083-
result = compiledWrapper.call(thisValue, exports, require, module,
1084-
filename, dirname);
1102+
result = ReflectApply(compiledWrapper, thisValue,
1103+
[exports, require, module, filename, dirname]);
10851104
}
10861105
hasLoadedAnyUserCJSModule = true;
10871106
if (requireDepth === 0) statCache = null;
@@ -1090,7 +1109,7 @@ Module.prototype._compile = function(content, filename) {
10901109

10911110
// Native extension for .js
10921111
Module._extensions['.js'] = function(module, filename) {
1093-
if (filename.endsWith('.js')) {
1112+
if (StringPrototypeEndsWith(filename, '.js')) {
10941113
const pkg = readPackageScope(filename);
10951114
// Function require shouldn't be used in ES modules.
10961115
if (pkg && pkg.data && pkg.data.type === 'module') {
@@ -1145,7 +1164,8 @@ Module._extensions['.node'] = function(module, filename) {
11451164
function createRequireFromPath(filename) {
11461165
// Allow a directory to be passed as the filename
11471166
const trailingSlash =
1148-
filename.endsWith('/') || (isWindows && filename.endsWith('\\'));
1167+
StringPrototypeEndsWith(filename, '/') ||
1168+
(isWindows && StringPrototypeEndsWith(filename, '\\'));
11491169

11501170
const proxyPath = trailingSlash ?
11511171
path.join(filename, 'noop.js') :
@@ -1207,15 +1227,16 @@ Module._initPaths = function() {
12071227
}
12081228

12091229
if (nodePath) {
1210-
paths = nodePath.split(path.delimiter).filter(function pathsFilterCB(path) {
1211-
return !!path;
1212-
}).concat(paths);
1230+
paths = ArrayPrototypeConcat(ArrayPrototypeFilter(
1231+
StringPrototypeSplit(nodePath, path.delimiter),
1232+
Boolean
1233+
), paths);
12131234
}
12141235

12151236
modulePaths = paths;
12161237

12171238
// Clone as a shallow copy, for introspection.
1218-
Module.globalPaths = modulePaths.slice(0);
1239+
Module.globalPaths = ArrayPrototypeSlice(modulePaths);
12191240
};
12201241

12211242
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)