Skip to content

Commit 6ad1a39

Browse files
committed
module: move helpers out of cjs loader
PR-URL: nodejs/node#49912 Backport-PR-URL: nodejs/node#50669 Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]>
1 parent ec2279a commit 6ad1a39

File tree

5 files changed

+78
-69
lines changed

5 files changed

+78
-69
lines changed

graal-nodejs/lib/internal/modules/cjs/loader.js

+6-60
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ const {
5656
StringPrototypeCharAt,
5757
StringPrototypeCharCodeAt,
5858
StringPrototypeEndsWith,
59-
StringPrototypeLastIndexOf,
6059
StringPrototypeIndexOf,
6160
StringPrototypeRepeat,
6261
StringPrototypeSlice,
@@ -69,7 +68,7 @@ const cjsParseCache = new SafeWeakMap();
6968

7069
// Set first due to cycle with ESM loader functions.
7170
module.exports = {
72-
wrapSafe, Module, toRealPath, readPackageScope, cjsParseCache,
71+
wrapSafe, Module, cjsParseCache,
7372
get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; },
7473
initializeCJS,
7574
};
@@ -89,9 +88,7 @@ const {
8988
const { internalCompileFunction } = require('internal/vm');
9089
const assert = require('internal/assert');
9190
const fs = require('fs');
92-
const internalFS = require('internal/fs/utils');
9391
const path = require('path');
94-
const { sep } = path;
9592
const { internalModuleStat } = internalBinding('fs');
9693
const { safeGetenv } = internalBinding('credentials');
9794
const {
@@ -107,6 +104,7 @@ const {
107104
makeRequireFunction,
108105
normalizeReferrerURL,
109106
stripBOM,
107+
toRealPath,
110108
} = require('internal/modules/helpers');
111109
const packageJsonReader = require('internal/modules/package_json_reader');
112110
const { getOptionValue, getEmbedderOptions } = require('internal/options');
@@ -402,15 +400,7 @@ function initializeCJS() {
402400
// -> a.<ext>
403401
// -> a/index.<ext>
404402

405-
/**
406-
* @param {string} requestPath
407-
* @return {PackageConfig}
408-
*/
409-
function readPackage(requestPath) {
410-
return packageJsonReader.read(path.resolve(requestPath, 'package.json'));
411-
}
412-
413-
let _readPackage = readPackage;
403+
let _readPackage = packageJsonReader.readPackage;
414404
ObjectDefineProperty(Module, '_readPackage', {
415405
__proto__: null,
416406
get() { return _readPackage; },
@@ -422,31 +412,6 @@ ObjectDefineProperty(Module, '_readPackage', {
422412
configurable: true,
423413
});
424414

425-
/**
426-
* Get the nearest parent package.json file from a given path.
427-
* Return the package.json data and the path to the package.json file, or false.
428-
* @param {string} checkPath The path to start searching from.
429-
*/
430-
function readPackageScope(checkPath) {
431-
const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, sep);
432-
let separatorIndex;
433-
do {
434-
separatorIndex = StringPrototypeLastIndexOf(checkPath, sep);
435-
checkPath = StringPrototypeSlice(checkPath, 0, separatorIndex);
436-
if (StringPrototypeEndsWith(checkPath, sep + 'node_modules')) {
437-
return false;
438-
}
439-
const pjson = _readPackage(checkPath + sep);
440-
if (pjson.exists) {
441-
return {
442-
data: pjson,
443-
path: checkPath,
444-
};
445-
}
446-
} while (separatorIndex > rootSeparatorIndex);
447-
return false;
448-
}
449-
450415
/**
451416
* Try to load a specifier as a package.
452417
* @param {string} requestPath The path to what we are trying to load
@@ -491,14 +456,6 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
491456
return actual;
492457
}
493458

494-
/**
495-
* Cache for storing resolved real paths of modules.
496-
* In order to minimize unnecessary lstat() calls, this cache is a list of known-real paths.
497-
* Set to an empty Map to reset.
498-
* @type {Map<string, string>}
499-
*/
500-
const realpathCache = new SafeMap();
501-
502459
/**
503460
* Check if the file exists and is not a directory if using `--preserve-symlinks` and `isMain` is false, keep symlinks
504461
* intact, otherwise resolve to the absolute realpath.
@@ -514,17 +471,6 @@ function tryFile(requestPath, isMain) {
514471
return toRealPath(requestPath);
515472
}
516473

517-
518-
/**
519-
* Resolves the path of a given `require` specifier, following symlinks.
520-
* @param {string} requestPath The `require` specifier
521-
*/
522-
function toRealPath(requestPath) {
523-
return fs.realpathSync(requestPath, {
524-
[internalFS.realpathCacheKey]: realpathCache,
525-
});
526-
}
527-
528474
/**
529475
* Given a path, check if the file exists with any of the set extensions.
530476
* @param {string} basePath The path and filename without extension
@@ -586,7 +532,7 @@ function trySelfParentPath(parent) {
586532
function trySelf(parentPath, request) {
587533
if (!parentPath) { return false; }
588534

589-
const { data: pkg, path: pkgPath } = readPackageScope(parentPath);
535+
const { data: pkg, path: pkgPath } = packageJsonReader.readPackageScope(parentPath);
590536
if (!pkg || pkg.exports == null || pkg.name === undefined) {
591537
return false;
592538
}
@@ -1143,7 +1089,7 @@ Module._resolveFilename = function(request, parent, isMain, options) {
11431089

11441090
if (request[0] === '#' && (parent?.filename || parent?.id === '<repl>')) {
11451091
const parentPath = parent?.filename ?? process.cwd() + path.sep;
1146-
const pkg = readPackageScope(parentPath) || { __proto__: null };
1092+
const pkg = packageJsonReader.readPackageScope(parentPath) || { __proto__: null };
11471093
if (pkg.data?.imports != null) {
11481094
try {
11491095
const { packageImportsResolve } = require('internal/modules/esm/resolve');
@@ -1431,7 +1377,7 @@ Module._extensions['.js'] = function(module, filename) {
14311377
content = fs.readFileSync(filename, 'utf8');
14321378
}
14331379
if (StringPrototypeEndsWith(filename, '.js')) {
1434-
const pkg = readPackageScope(filename) || { __proto__: null };
1380+
const pkg = packageJsonReader.readPackageScope(filename) || { __proto__: null };
14351381
// Function require shouldn't be used in ES modules.
14361382
if (pkg.data?.type === 'module') {
14371383
const parent = moduleParentCache.get(module);

graal-nodejs/lib/internal/modules/helpers.js

+20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const {
2121
const { BuiltinModule } = require('internal/bootstrap/realm');
2222

2323
const { validateString } = require('internal/validators');
24+
const fs = require('fs'); // Import all of `fs` so that it can be monkey-patched.
25+
const internalFS = require('internal/fs/utils');
2426
const path = require('path');
2527
const { pathToFileURL, fileURLToPath, URL } = require('internal/url');
2628

@@ -39,6 +41,23 @@ let debug = require('internal/util/debuglog').debuglog('module', (fn) => {
3941

4042
/** @typedef {import('internal/modules/cjs/loader.js').Module} Module */
4143

44+
/**
45+
* Cache for storing resolved real paths of modules.
46+
* In order to minimize unnecessary lstat() calls, this cache is a list of known-real paths.
47+
* Set to an empty Map to reset.
48+
* @type {Map<string, string>}
49+
*/
50+
const realpathCache = new SafeMap();
51+
/**
52+
* Resolves the path of a given `require` specifier, following symlinks.
53+
* @param {string} requestPath The `require` specifier
54+
*/
55+
function toRealPath(requestPath) {
56+
return fs.realpathSync(requestPath, {
57+
[internalFS.realpathCacheKey]: realpathCache,
58+
});
59+
}
60+
4261
/** @type {Set<string>} */
4362
let cjsConditions;
4463
/**
@@ -310,4 +329,5 @@ module.exports = {
310329
makeRequireFunction,
311330
normalizeReferrerURL,
312331
stripBOM,
332+
toRealPath,
313333
};

graal-nodejs/lib/internal/modules/package_json_reader.js

+43-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ const {
44
JSONParse,
55
ObjectPrototypeHasOwnProperty,
66
SafeMap,
7+
StringPrototypeEndsWith,
8+
StringPrototypeIndexOf,
9+
StringPrototypeLastIndexOf,
10+
StringPrototypeSlice,
711
} = primordials;
812
const {
913
ERR_INVALID_PACKAGE_CONFIG,
1014
} = require('internal/errors').codes;
1115
const { internalModuleReadJSON } = internalBinding('fs');
12-
const { toNamespacedPath } = require('path');
16+
const { resolve, sep, toNamespacedPath } = require('path');
1317
const { kEmptyObject } = require('internal/util');
1418

1519
const { fileURLToPath, pathToFileURL } = require('internal/url');
@@ -128,4 +132,41 @@ function read(jsonPath, { base, specifier, isESM } = kEmptyObject) {
128132
return result;
129133
}
130134

131-
module.exports = { read };
135+
/**
136+
* @param {string} requestPath
137+
* @return {PackageConfig}
138+
*/
139+
function readPackage(requestPath) {
140+
return read(resolve(requestPath, 'package.json'));
141+
}
142+
143+
/**
144+
* Get the nearest parent package.json file from a given path.
145+
* Return the package.json data and the path to the package.json file, or false.
146+
* @param {string} checkPath The path to start searching from.
147+
*/
148+
function readPackageScope(checkPath) {
149+
const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, sep);
150+
let separatorIndex;
151+
do {
152+
separatorIndex = StringPrototypeLastIndexOf(checkPath, sep);
153+
checkPath = StringPrototypeSlice(checkPath, 0, separatorIndex);
154+
if (StringPrototypeEndsWith(checkPath, sep + 'node_modules')) {
155+
return false;
156+
}
157+
const pjson = readPackage(checkPath + sep);
158+
if (pjson.exists) {
159+
return {
160+
data: pjson,
161+
path: checkPath,
162+
};
163+
}
164+
} while (separatorIndex > rootSeparatorIndex);
165+
return false;
166+
}
167+
168+
module.exports = {
169+
read,
170+
readPackage,
171+
readPackageScope,
172+
};

graal-nodejs/lib/internal/modules/run_main.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ function resolveMainPath(main) {
1616
// Note extension resolution for the main entry point can be deprecated in a
1717
// future major.
1818
// Module._findPath is monkey-patchable here.
19-
const { Module, toRealPath } = require('internal/modules/cjs/loader');
19+
const { Module } = require('internal/modules/cjs/loader');
2020
let mainPath = Module._findPath(path.resolve(main), null, true);
2121
if (!mainPath) { return; }
2222

2323
const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main');
2424
if (!preserveSymlinksMain) {
25+
const { toRealPath } = require('internal/modules/helpers');
2526
mainPath = toRealPath(mainPath);
2627
}
2728

@@ -51,10 +52,11 @@ function shouldUseESMLoader(mainPath) {
5152
if (esModuleSpecifierResolution === 'node') {
5253
return true;
5354
}
54-
const { readPackageScope } = require('internal/modules/cjs/loader');
5555
// Determine the module format of the main
5656
if (mainPath && StringPrototypeEndsWith(mainPath, '.mjs')) { return true; }
5757
if (!mainPath || StringPrototypeEndsWith(mainPath, '.cjs')) { return false; }
58+
59+
const { readPackageScope } = require('internal/modules/package_json_reader');
5860
const pkg = readPackageScope(mainPath);
5961
return pkg && pkg.data.type === 'module';
6062
}

graal-nodejs/test/fixtures/errors/force_colors.snapshot

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ throw new Error('Should include grayed stack trace')
44

55
Error: Should include grayed stack trace
66
at Object.<anonymous> (/test*force_colors.js:1:7)
7-
 at Module._compile (node:internal*modules*cjs*loader:1244:14)
8-
 at Module._extensions..js (node:internal*modules*cjs*loader:1298:10)
9-
 at Module.load (node:internal*modules*cjs*loader:1101:32)
10-
 at Module._load (node:internal*modules*cjs*loader:942:12)
11-
 at Function.executeUserEntryPoint [as runMain] (node:internal*modules*run_main:88:12)
7+
 at Module._compile (node:internal*modules*cjs*loader:1356:14)
8+
 at Module._extensions..js (node:internal*modules*cjs*loader:1414:10)
9+
 at Module.load (node:internal*modules*cjs*loader:1197:32)
10+
 at Module._load (node:internal*modules*cjs*loader:1013:12)
11+
 at Function.executeUserEntryPoint [as runMain] (node:internal*modules*run_main:109:12)
1212
 at node:internal*main*run_main_module:23:47
1313

1414
Node.js *

0 commit comments

Comments
 (0)