Skip to content

Commit 15530fe

Browse files
anonrigRafaelGSS
authored andcommitted
lib: merge cjs and esm package json reader caches
PR-URL: #48477 Reviewed-By: Jacob Smith <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Mohammed Keyvanzadeh <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 1b2b930 commit 15530fe

File tree

10 files changed

+198
-217
lines changed

10 files changed

+198
-217
lines changed

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

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ const{
8282
pendingDeprecate,
8383
emitExperimentalWarning,
8484
kEmptyObject,
85-
filterOwnProperties,
8685
setOwnProperty,
8786
getLazy,
8887
}=require('internal/util');
@@ -355,36 +354,12 @@ function initializeCJS(){
355354
// -> a.<ext>
356355
// -> a/index.<ext>
357356

358-
constpackageJsonCache=newSafeMap();
359-
357+
/**
358+
* @param{string} requestPath
359+
* @return{PackageConfig}
360+
*/
360361
functionreadPackage(requestPath){
361-
constjsonPath=path.resolve(requestPath,'package.json');
362-
363-
constexisting=packageJsonCache.get(jsonPath);
364-
if(existing!==undefined)returnexisting;
365-
366-
constresult=packageJsonReader.read(jsonPath);
367-
constjson=result.containsKeys===false ? '{}' : result.string;
368-
if(json===undefined){
369-
packageJsonCache.set(jsonPath,false);
370-
returnfalse;
371-
}
372-
373-
try{
374-
constfiltered=filterOwnProperties(JSONParse(json),[
375-
'name',
376-
'main',
377-
'exports',
378-
'imports',
379-
'type',
380-
]);
381-
packageJsonCache.set(jsonPath,filtered);
382-
returnfiltered;
383-
}catch(e){
384-
e.path=jsonPath;
385-
e.message='Error parsing '+jsonPath+': '+e.message;
386-
throwe;
387-
}
362+
returnpackageJsonReader.read(path.resolve(requestPath,'package.json'));
388363
}
389364

390365
let_readPackage=readPackage;
@@ -414,7 +389,7 @@ function readPackageScope(checkPath){
414389
if(StringPrototypeEndsWith(checkPath,sep+'node_modules'))
415390
returnfalse;
416391
constpjson=_readPackage(checkPath+sep);
417-
if(pjson)return{
392+
if(pjson.exists)return{
418393
data: pjson,
419394
path: checkPath,
420395
};
@@ -423,7 +398,7 @@ function readPackageScope(checkPath){
423398
}
424399

425400
functiontryPackage(requestPath,exts,isMain,originalPath){
426-
constpkg=_readPackage(requestPath)?.main;
401+
constpkg=_readPackage(requestPath).main;
427402

428403
if(!pkg){
429404
returntryExtensions(path.resolve(requestPath,'index'),exts,isMain);
@@ -528,9 +503,10 @@ function trySelfParentPath(parent){
528503
functiontrySelf(parentPath,request){
529504
if(!parentPath)returnfalse;
530505

531-
const{data: pkg,path: pkgPath}=readPackageScope(parentPath)||{};
532-
if(!pkg||pkg.exports===undefined)returnfalse;
533-
if(typeofpkg.name!=='string')returnfalse;
506+
const{data: pkg,path: pkgPath}=readPackageScope(parentPath);
507+
if(!pkg||pkg.exports==null||pkg.name===undefined){
508+
returnfalse;
509+
}
534510

535511
letexpansion;
536512
if(request===pkg.name){
@@ -565,7 +541,7 @@ function resolveExports(nmPath, request){
565541
return;
566542
constpkgPath=path.resolve(nmPath,name);
567543
constpkg=_readPackage(pkgPath);
568-
if(pkg?.exports!=null){
544+
if(pkg.exists&&pkg.exports!=null){
569545
try{
570546
const{ packageExportsResolve }=require('internal/modules/esm/resolve');
571547
returnfinalizeEsmResolution(packageExportsResolve(
@@ -1028,7 +1004,7 @@ Module._resolveFilename = function(request, parent, isMain, options){
10281004

10291005
if(request[0]==='#'&&(parent?.filename||parent?.id==='<repl>')){
10301006
constparentPath=parent?.filename??process.cwd()+path.sep;
1031-
constpkg=readPackageScope(parentPath)||{};
1007+
constpkg=readPackageScope(parentPath)||{__proto__: null};
10321008
if(pkg.data?.imports!=null){
10331009
try{
10341010
const{ packageImportsResolve }=require('internal/modules/esm/resolve');
@@ -1274,9 +1250,9 @@ Module._extensions['.js'] = function(module, filename){
12741250
content=fs.readFileSync(filename,'utf8');
12751251
}
12761252
if(StringPrototypeEndsWith(filename,'.js')){
1277-
constpkg=readPackageScope(filename);
1253+
constpkg=readPackageScope(filename)||{__proto__: null};
12781254
// Function require shouldn't be used in ES modules.
1279-
if(pkg?.data?.type==='module'){
1255+
if(pkg.data?.type==='module'){
12801256
constparent=moduleParentCache.get(module);
12811257
constparentPath=parent?.filename;
12821258
constpackageJsonPath=path.resolve(pkg.path,'package.json');
Lines changed: 8 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,10 @@
11
'use strict';
22

33
const{
4-
JSONParse,
5-
ObjectPrototypeHasOwnProperty,
6-
SafeMap,
74
StringPrototypeEndsWith,
85
}=primordials;
96
const{URL, fileURLToPath }=require('internal/url');
10-
const{
11-
ERR_INVALID_PACKAGE_CONFIG,
12-
}=require('internal/errors').codes;
13-
14-
const{ filterOwnProperties }=require('internal/util');
15-
16-
17-
/**
18-
* @typedef{string | string[] | Record<string, unknown>} Exports
19-
* @typedef{'module' | 'commonjs'} PackageType
20-
* @typedef{{
21-
* pjsonPath: string,
22-
* exports?: ExportConfig,
23-
* name?: string,
24-
* main?: string,
25-
* type?: PackageType,
26-
* }} PackageConfig
27-
*/
28-
29-
/** @type{Map<string, PackageConfig>} */
30-
constpackageJSONCache=newSafeMap();
31-
32-
33-
/**
34-
* @param{string} path
35-
* @param{string} specifier
36-
* @param{string | URL | undefined} base
37-
* @returns{PackageConfig}
38-
*/
39-
functiongetPackageConfig(path,specifier,base){
40-
constexisting=packageJSONCache.get(path);
41-
if(existing!==undefined){
42-
returnexisting;
43-
}
44-
constpackageJsonReader=require('internal/modules/package_json_reader');
45-
constsource=packageJsonReader.read(path).string;
46-
if(source===undefined){
47-
constpackageConfig={
48-
pjsonPath: path,
49-
exists: false,
50-
main: undefined,
51-
name: undefined,
52-
type: 'none',
53-
exports: undefined,
54-
imports: undefined,
55-
};
56-
packageJSONCache.set(path,packageConfig);
57-
returnpackageConfig;
58-
}
59-
60-
letpackageJSON;
61-
try{
62-
packageJSON=JSONParse(source);
63-
}catch(error){
64-
thrownewERR_INVALID_PACKAGE_CONFIG(
65-
path,
66-
(base ? `"${specifier}" from ` : '')+fileURLToPath(base||specifier),
67-
error.message,
68-
);
69-
}
70-
71-
let{ imports, main, name, type }=filterOwnProperties(packageJSON,['imports','main','name','type']);
72-
constexports=ObjectPrototypeHasOwnProperty(packageJSON,'exports') ? packageJSON.exports : undefined;
73-
if(typeofimports!=='object'||imports===null){
74-
imports=undefined;
75-
}
76-
if(typeofmain!=='string'){
77-
main=undefined;
78-
}
79-
if(typeofname!=='string'){
80-
name=undefined;
81-
}
82-
// Ignore unknown types for forwards compatibility
83-
if(type!=='module'&&type!=='commonjs'){
84-
type='none';
85-
}
86-
87-
constpackageConfig={
88-
pjsonPath: path,
89-
exists: true,
90-
main,
91-
name,
92-
type,
93-
exports,
94-
imports,
95-
};
96-
packageJSONCache.set(path,packageConfig);
97-
returnpackageConfig;
98-
}
99-
7+
constpackageJsonReader=require('internal/modules/package_json_reader');
1008

1019
/**
10210
* @param{URL | string} resolved
@@ -109,7 +17,11 @@ function getPackageScopeConfig(resolved){
10917
if(StringPrototypeEndsWith(packageJSONPath,'node_modules/package.json')){
11018
break;
11119
}
112-
constpackageConfig=getPackageConfig(fileURLToPath(packageJSONUrl),resolved);
20+
constpackageConfig=packageJsonReader.read(fileURLToPath(packageJSONUrl),{
21+
__proto__: null,
22+
specifier: resolved,
23+
isESM: true,
24+
});
11325
if(packageConfig.exists){
11426
returnpackageConfig;
11527
}
@@ -124,7 +36,8 @@ function getPackageScopeConfig(resolved){
12436
}
12537
}
12638
constpackageJSONPath=fileURLToPath(packageJSONUrl);
127-
constpackageConfig={
39+
return{
40+
__proto__: null,
12841
pjsonPath: packageJSONPath,
12942
exists: false,
13043
main: undefined,
@@ -133,12 +46,9 @@ function getPackageScopeConfig(resolved){
13346
exports: undefined,
13447
imports: undefined,
13548
};
136-
packageJSONCache.set(packageJSONPath,packageConfig);
137-
returnpackageConfig;
13849
}
13950

14051

14152
module.exports={
142-
getPackageConfig,
14353
getPackageScopeConfig,
14454
};

‎lib/internal/modules/esm/resolve.js‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ const{
5353
}=require('internal/errors').codes;
5454

5555
const{Module: CJSModule}=require('internal/modules/cjs/loader');
56-
const{getPackageConfig,getPackageScopeConfig }=require('internal/modules/esm/package_config');
56+
const{ getPackageScopeConfig }=require('internal/modules/esm/package_config');
5757
const{ getConditionsSet }=require('internal/modules/esm/utils');
58+
constpackageJsonReader=require('internal/modules/package_json_reader');
5859
const{ internalModuleStat }=internalBinding('fs');
5960

6061
/**
@@ -734,8 +735,7 @@ function packageResolve(specifier, base, conditions){
734735
constpackageConfig=getPackageScopeConfig(base);
735736
if(packageConfig.exists){
736737
constpackageJSONUrl=pathToFileURL(packageConfig.pjsonPath);
737-
if(packageConfig.name===packageName&&
738-
packageConfig.exports!==undefined&&packageConfig.exports!==null){
738+
if(packageConfig.exports!=null&&packageConfig.name===packageName){
739739
returnpackageExportsResolve(
740740
packageJSONUrl,packageSubpath,packageConfig,base,conditions);
741741
}
@@ -759,8 +759,8 @@ function packageResolve(specifier, base, conditions){
759759
}
760760

761761
// Package match.
762-
constpackageConfig=getPackageConfig(packageJSONPath,specifier,base);
763-
if(packageConfig.exports!==undefined&&packageConfig.exports!==null){
762+
constpackageConfig=packageJsonReader.read(packageJSONPath,{__proto__: null,specifier, base,isESM: true});
763+
if(packageConfig.exports!=null){
764764
returnpackageExportsResolve(
765765
packageJSONUrl,packageSubpath,packageConfig,base,conditions);
766766
}

0 commit comments

Comments
(0)