Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 36b68db

Browse filesBrowse files
michaelsmithxyzaduh95
authored andcommitted
src: reduce the nearest parent package JSON cache size
PR-URL: #59888 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 26b40ba commit 36b68db
Copy full SHA for 36b68db

File tree

Expand file treeCollapse file tree

4 files changed

+52
-46
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+52
-46
lines changed
Open diff view settings
Collapse file

‎lib/internal/modules/package_json_reader.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/package_json_reader.js
+52-4Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ const {
66
ObjectDefineProperty,
77
RegExpPrototypeExec,
88
SafeMap,
9+
StringPrototypeEndsWith,
910
StringPrototypeIndexOf,
11+
StringPrototypeLastIndexOf,
1012
StringPrototypeSlice,
1113
} = primordials;
1214
const {
@@ -26,6 +28,7 @@ const {
2628
const { kEmptyObject } = require('internal/util');
2729
const modulesBinding = internalBinding('modules');
2830
const path = require('path');
31+
const permission = require('internal/process/permission');
2932
const { validateString } = require('internal/validators');
3033
const internalFsBinding = internalBinding('fs');
3134

@@ -127,26 +130,71 @@ function read(jsonPath, { base, specifier, isESM } = kEmptyObject) {
127130
};
128131
}
129132

133+
/**
134+
* Given a file path, walk the filesystem upwards until we find its closest parent
135+
* `package.json` file, stopping when:
136+
* 1. we find a `package.json` file;
137+
* 2. we find a path that we do not have permission to read;
138+
* 3. we find a containing `node_modules` directory;
139+
* 4. or, we reach the filesystem root
140+
* @returns {undefined | string}
141+
*/
142+
function findParentPackageJSON(checkPath) {
143+
const enabledPermission = permission.isEnabled();
144+
145+
const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, path.sep);
146+
let separatorIndex;
147+
148+
do {
149+
separatorIndex = StringPrototypeLastIndexOf(checkPath, path.sep);
150+
checkPath = StringPrototypeSlice(checkPath, 0, separatorIndex);
151+
152+
if (enabledPermission && !permission.has('fs.read', checkPath + path.sep)) {
153+
return undefined;
154+
}
155+
156+
if (StringPrototypeEndsWith(checkPath, path.sep + 'node_modules')) {
157+
return undefined;
158+
}
159+
160+
const maybePackageJSONPath = checkPath + path.sep + 'package.json';
161+
const stat = internalFsBinding.internalModuleStat(checkPath + path.sep + 'package.json');
162+
163+
const packageJSONExists = stat === 0;
164+
if (packageJSONExists) {
165+
return maybePackageJSONPath;
166+
}
167+
} while (separatorIndex > rootSeparatorIndex);
168+
169+
return undefined;
170+
}
171+
130172
/**
131173
* Get the nearest parent package.json file from a given path.
132174
* Return the package.json data and the path to the package.json file, or undefined.
133175
* @param {string} checkPath The path to start searching from.
134176
* @returns {undefined | DeserializedPackageConfig}
135177
*/
136178
function getNearestParentPackageJSON(checkPath) {
137-
if (nearestParentPackageJSONCache.has(checkPath)) {
138-
return nearestParentPackageJSONCache.get(checkPath);
179+
const nearestParentPackageJSON = findParentPackageJSON(checkPath);
180+
181+
if (nearestParentPackageJSON === undefined) {
182+
return undefined;
183+
}
184+
185+
if (nearestParentPackageJSONCache.has(nearestParentPackageJSON)) {
186+
return nearestParentPackageJSONCache.get(nearestParentPackageJSON);
139187
}
140188

141-
const result = modulesBinding.getNearestParentPackageJSON(checkPath);
189+
const result = modulesBinding.readPackageJSON(nearestParentPackageJSON);
142190

143191
if (result === undefined) {
144192
nearestParentPackageJSONCache.set(checkPath, undefined);
145193
return undefined;
146194
}
147195

148196
const packageConfig = deserializePackageJSON(checkPath, result);
149-
nearestParentPackageJSONCache.set(checkPath, packageConfig);
197+
nearestParentPackageJSONCache.set(nearestParentPackageJSON, packageConfig);
150198

151199
return packageConfig;
152200
}
Collapse file

‎src/node_modules.cc‎

Copy file name to clipboardExpand all lines: src/node_modules.cc
-39Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -315,40 +315,6 @@ const BindingData::PackageConfig* BindingData::TraverseParent(
315315
return nullptr;
316316
}
317317

318-
void BindingData::GetNearestParentPackageJSON(
319-
const v8::FunctionCallbackInfo<v8::Value>& args) {
320-
CHECK_GE(args.Length(), 1);
321-
CHECK(args[0]->IsString());
322-
323-
Realm* realm = Realm::GetCurrent(args);
324-
BufferValue path_value(realm->isolate(), args[0]);
325-
// Check if the path has a trailing slash. If so, add it after
326-
// ToNamespacedPath() as it will be deleted by ToNamespacedPath()
327-
bool slashCheck = path_value.ToStringView().ends_with(kPathSeparator);
328-
329-
ToNamespacedPath(realm->env(), &path_value);
330-
331-
std::string path_value_str = path_value.ToString();
332-
if (slashCheck) {
333-
path_value_str.push_back(kPathSeparator);
334-
}
335-
336-
std::filesystem::path path;
337-
338-
#ifdef _WIN32
339-
std::wstring wide_path = ConvertToWideString(path_value_str, GetACP());
340-
path = std::filesystem::path(wide_path);
341-
#else
342-
path = std::filesystem::path(path_value_str);
343-
#endif
344-
345-
auto package_json = TraverseParent(realm, path);
346-
347-
if (package_json != nullptr) {
348-
args.GetReturnValue().Set(package_json->Serialize(realm));
349-
}
350-
}
351-
352318
void BindingData::GetNearestParentPackageJSONType(
353319
const FunctionCallbackInfo<Value>& args) {
354320
CHECK_GE(args.Length(), 1);
@@ -597,10 +563,6 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
597563
target,
598564
"getNearestParentPackageJSONType",
599565
GetNearestParentPackageJSONType);
600-
SetMethod(isolate,
601-
target,
602-
"getNearestParentPackageJSON",
603-
GetNearestParentPackageJSON);
604566
SetMethod(
605567
isolate, target, "getPackageScopeConfig", GetPackageScopeConfig<false>);
606568
SetMethod(isolate, target, "getPackageType", GetPackageScopeConfig<true>);
@@ -636,7 +598,6 @@ void BindingData::RegisterExternalReferences(
636598
ExternalReferenceRegistry* registry) {
637599
registry->Register(ReadPackageJSON);
638600
registry->Register(GetNearestParentPackageJSONType);
639-
registry->Register(GetNearestParentPackageJSON);
640601
registry->Register(GetPackageScopeConfig<false>);
641602
registry->Register(GetPackageScopeConfig<true>);
642603
registry->Register(EnableCompileCache);
Collapse file

‎src/node_modules.h‎

Copy file name to clipboardExpand all lines: src/node_modules.h
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ class BindingData : public SnapshotableObject {
5555
SET_MEMORY_INFO_NAME(BindingData)
5656

5757
static void ReadPackageJSON(const v8::FunctionCallbackInfo<v8::Value>& args);
58-
static void GetNearestParentPackageJSON(
59-
const v8::FunctionCallbackInfo<v8::Value>& args);
6058
static void GetNearestParentPackageJSONType(
6159
const v8::FunctionCallbackInfo<v8::Value>& args);
6260
template <bool return_only_type>
Collapse file

‎typings/internalBinding/modules.d.ts‎

Copy file name to clipboardExpand all lines: typings/internalBinding/modules.d.ts
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export type SerializedPackageConfig = [
2323
export interface ModulesBinding {
2424
readPackageJSON(path: string): SerializedPackageConfig | undefined;
2525
getNearestParentPackageJSONType(path: string): PackageConfig['type']
26-
getNearestParentPackageJSON(path: string): SerializedPackageConfig | undefined
2726
getPackageScopeConfig(path: string): SerializedPackageConfig | undefined
2827
getPackageType(path: string): PackageConfig['type'] | undefined
2928
enableCompileCache(path?: string): { status: number, message?: string, directory?: string }

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.