Skip to content

Commit 2ff4e71

Browse files
GeoffreyBoothtargos
authored andcommitted
module: move helpers out of cjs loader
PR-URL: #49912 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 5c66ec9 commit 2ff4e71

4 files changed

Lines changed: 79 additions & 70 deletions

File tree

‎lib/internal/modules/cjs/loader.js‎

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ const {
5555
StringPrototypeCharAt,
5656
StringPrototypeCharCodeAt,
5757
StringPrototypeEndsWith,
58-
StringPrototypeLastIndexOf,
5958
StringPrototypeIndexOf,
6059
StringPrototypeRepeat,
6160
StringPrototypeSlice,
@@ -68,7 +67,7 @@ const cjsParseCache = new SafeWeakMap();
6867

6968
// Set first due to cycle with ESM loader functions.
7069
module.exports={
71-
wrapSafe, Module,toRealPath, readPackageScope,cjsParseCache,
70+
wrapSafe, Module, cjsParseCache,
7271
gethasLoadedAnyUserCJSModule(){returnhasLoadedAnyUserCJSModule;},
7372
initializeCJS,
7473
};
@@ -88,9 +87,7 @@ const {
8887
const{ internalCompileFunction }=require('internal/vm');
8988
constassert=require('internal/assert');
9089
constfs=require('fs');
91-
constinternalFS=require('internal/fs/utils');
9290
constpath=require('path');
93-
const{ sep }=path;
9491
const{ internalModuleStat }=internalBinding('fs');
9592
const{ safeGetenv }=internalBinding('credentials');
9693
const{
@@ -106,6 +103,7 @@ const {
106103
makeRequireFunction,
107104
normalizeReferrerURL,
108105
stripBOM,
106+
toRealPath,
109107
}=require('internal/modules/helpers');
110108
constpackageJsonReader=require('internal/modules/package_json_reader');
111109
const{ getOptionValue, getEmbedderOptions }=require('internal/options');
@@ -403,15 +401,7 @@ function initializeCJS() {
403401
// -> a.<ext>
404402
// -> a/index.<ext>
405403

406-
/**
407-
* @param {string} requestPath
408-
* @return {PackageConfig}
409-
*/
410-
functionreadPackage(requestPath){
411-
returnpackageJsonReader.read(path.resolve(requestPath,'package.json'));
412-
}
413-
414-
let_readPackage=readPackage;
404+
let_readPackage=packageJsonReader.readPackage;
415405
ObjectDefineProperty(Module,'_readPackage',{
416406
__proto__: null,
417407
get(){return_readPackage;},
@@ -423,37 +413,6 @@ ObjectDefineProperty(Module, '_readPackage', {
423413
configurable: true,
424414
});
425415

426-
/**
427-
* Get the nearest parent package.json file from a given path.
428-
* Return the package.json data and the path to the package.json file, or false.
429-
* @param {string} checkPath The path to start searching from.
430-
*/
431-
functionreadPackageScope(checkPath){
432-
constrootSeparatorIndex=StringPrototypeIndexOf(checkPath,sep);
433-
letseparatorIndex;
434-
constenabledPermission=permission.isEnabled();
435-
do{
436-
separatorIndex=StringPrototypeLastIndexOf(checkPath,sep);
437-
checkPath=StringPrototypeSlice(checkPath,0,separatorIndex);
438-
// Stop the search when the process doesn't have permissions
439-
// to walk upwards
440-
if(enabledPermission&&!permission.has('fs.read',checkPath+sep)){
441-
returnfalse;
442-
}
443-
if(StringPrototypeEndsWith(checkPath,sep+'node_modules')){
444-
returnfalse;
445-
}
446-
constpjson=_readPackage(checkPath+sep);
447-
if(pjson.exists){
448-
return{
449-
data: pjson,
450-
path: checkPath,
451-
};
452-
}
453-
}while(separatorIndex>rootSeparatorIndex);
454-
returnfalse;
455-
}
456-
457416
/**
458417
* Try to load a specifier as a package.
459418
* @param {string} requestPath The path to what we are trying to load
@@ -498,14 +457,6 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
498457
returnactual;
499458
}
500459

501-
/**
502-
* Cache for storing resolved real paths of modules.
503-
* In order to minimize unnecessary lstat() calls, this cache is a list of known-real paths.
504-
* Set to an empty Map to reset.
505-
* @type {Map<string, string>}
506-
*/
507-
constrealpathCache=newSafeMap();
508-
509460
/**
510461
* Check if the file exists and is not a directory if using `--preserve-symlinks` and `isMain` is false, keep symlinks
511462
* intact, otherwise resolve to the absolute realpath.
@@ -521,17 +472,6 @@ function tryFile(requestPath, isMain) {
521472
returntoRealPath(requestPath);
522473
}
523474

524-
525-
/**
526-
* Resolves the path of a given `require` specifier, following symlinks.
527-
* @param {string} requestPath The `require` specifier
528-
*/
529-
functiontoRealPath(requestPath){
530-
returnfs.realpathSync(requestPath,{
531-
[internalFS.realpathCacheKey]: realpathCache,
532-
});
533-
}
534-
535475
/**
536476
* Given a path, check if the file exists with any of the set extensions.
537477
* @param {string} basePath The path and filename without extension
@@ -593,7 +533,7 @@ function trySelfParentPath(parent) {
593533
functiontrySelf(parentPath,request){
594534
if(!parentPath){returnfalse;}
595535

596-
const{data: pkg,path: pkgPath}=readPackageScope(parentPath);
536+
const{data: pkg,path: pkgPath}=packageJsonReader.readPackageScope(parentPath);
597537
if(!pkg||pkg.exports==null||pkg.name===undefined){
598538
returnfalse;
599539
}
@@ -1153,7 +1093,7 @@ Module._resolveFilename = function(request, parent, isMain, options) {
11531093

11541094
if(request[0]==='#'&&(parent?.filename||parent?.id==='<repl>')){
11551095
constparentPath=parent?.filename??process.cwd()+path.sep;
1156-
constpkg=readPackageScope(parentPath)||{__proto__: null};
1096+
constpkg=packageJsonReader.readPackageScope(parentPath)||{__proto__: null};
11571097
if(pkg.data?.imports!=null){
11581098
try{
11591099
const{ packageImportsResolve }=require('internal/modules/esm/resolve');
@@ -1450,7 +1390,7 @@ Module._extensions['.js'] = function(module, filename) {
14501390
content=fs.readFileSync(filename,'utf8');
14511391
}
14521392
if(StringPrototypeEndsWith(filename,'.js')){
1453-
constpkg=readPackageScope(filename)||{__proto__: null};
1393+
constpkg=packageJsonReader.readPackageScope(filename)||{__proto__: null};
14541394
// Function require shouldn't be used in ES modules.
14551395
if(pkg.data?.type==='module'){
14561396
constparent=moduleParentCache.get(module);

‎lib/internal/modules/helpers.js‎

Lines changed: 20 additions & 0 deletions
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+
constfs=require('fs');// Import all of `fs` so that it can be monkey-patched.
25+
constinternalFS=require('internal/fs/utils');
2426
constpath=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+
constrealpathCache=newSafeMap();
51+
/**
52+
* Resolves the path of a given `require` specifier, following symlinks.
53+
* @param {string} requestPath The `require` specifier
54+
*/
55+
functiontoRealPath(requestPath){
56+
returnfs.realpathSync(requestPath,{
57+
[internalFS.realpathCacheKey]: realpathCache,
58+
});
59+
}
60+
4261
/** @type {Set<string>} */
4362
letcjsConditions;
4463
/**
@@ -310,4 +329,5 @@ module.exports = {
310329
makeRequireFunction,
311330
normalizeReferrerURL,
312331
stripBOM,
332+
toRealPath,
313333
};

‎lib/internal/modules/package_json_reader.js‎

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ 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');
17+
constpermission=require('internal/process/permission');
1318
const{ kEmptyObject }=require('internal/util');
1419

1520
const{ fileURLToPath, pathToFileURL }=require('internal/url');
@@ -128,4 +133,47 @@ function read(jsonPath, { base, specifier, isESM } = kEmptyObject) {
128133
returnresult;
129134
}
130135

131-
module.exports={ read };
136+
/**
137+
* @param {string} requestPath
138+
* @return {PackageConfig}
139+
*/
140+
functionreadPackage(requestPath){
141+
returnread(resolve(requestPath,'package.json'));
142+
}
143+
144+
/**
145+
* Get the nearest parent package.json file from a given path.
146+
* Return the package.json data and the path to the package.json file, or false.
147+
* @param {string} checkPath The path to start searching from.
148+
*/
149+
functionreadPackageScope(checkPath){
150+
constrootSeparatorIndex=StringPrototypeIndexOf(checkPath,sep);
151+
letseparatorIndex;
152+
constenabledPermission=permission.isEnabled();
153+
do{
154+
separatorIndex=StringPrototypeLastIndexOf(checkPath,sep);
155+
checkPath=StringPrototypeSlice(checkPath,0,separatorIndex);
156+
// Stop the search when the process doesn't have permissions
157+
// to walk upwards
158+
if(enabledPermission&&!permission.has('fs.read',checkPath+sep)){
159+
returnfalse;
160+
}
161+
if(StringPrototypeEndsWith(checkPath,sep+'node_modules')){
162+
returnfalse;
163+
}
164+
constpjson=readPackage(checkPath+sep);
165+
if(pjson.exists){
166+
return{
167+
data: pjson,
168+
path: checkPath,
169+
};
170+
}
171+
}while(separatorIndex>rootSeparatorIndex);
172+
returnfalse;
173+
}
174+
175+
module.exports={
176+
read,
177+
readPackage,
178+
readPackageScope,
179+
};

‎lib/internal/modules/run_main.js‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ function resolveMainPath(main) {
1515
// Note extension resolution for the main entry point can be deprecated in a
1616
// future major.
1717
// Module._findPath is monkey-patchable here.
18-
const{ Module, toRealPath}=require('internal/modules/cjs/loader');
18+
const{ Module }=require('internal/modules/cjs/loader');
1919
letmainPath=Module._findPath(path.resolve(main),null,true);
2020
if(!mainPath){return;}
2121

2222
constpreserveSymlinksMain=getOptionValue('--preserve-symlinks-main');
2323
if(!preserveSymlinksMain){
24+
const{ toRealPath }=require('internal/modules/helpers');
2425
mainPath=toRealPath(mainPath);
2526
}
2627

@@ -48,7 +49,7 @@ function shouldUseESMLoader(mainPath) {
4849
if(mainPath&&StringPrototypeEndsWith(mainPath,'.mjs')){returntrue;}
4950
if(!mainPath||StringPrototypeEndsWith(mainPath,'.cjs')){returnfalse;}
5051

51-
const{ readPackageScope }=require('internal/modules/cjs/loader');
52+
const{ readPackageScope }=require('internal/modules/package_json_reader');
5253
constpkg=readPackageScope(mainPath);
5354
// No need to guard `pkg` as it can only be an object or `false`.
5455
returnpkg.data?.type==='module'||getOptionValue('--experimental-default-type')==='module';

0 commit comments

Comments
 (0)