Skip to content

Commit 93bd576

Browse files
committed
vfs: address review feedback for module_hooks and file_system
- Use getLazy() for fs, fs/promises, and Module requires to avoid circular dependencies during bootstrap - Use kEmptyObject as default constructor options in VirtualFileSystem - Replace .then().catch() with .then(success, error) in callback methods - Add JSDoc explaining why urlToPath differs from toPathIfFileURL PR-URL: #61478
1 parent 77ad8b8 commit 93bd576

File tree

2 files changed

+29
-36
lines changed

2 files changed

+29
-36
lines changed

lib/internal/vfs/file_system.js

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const {
5959
createEBADF,
6060
} = require('internal/vfs/errors');
6161
const { VirtualReadStream } = require('internal/vfs/streams');
62-
const { emitExperimentalWarning } = require('internal/util');
62+
const { emitExperimentalWarning, kEmptyObject } = require('internal/util');
6363

6464
// Private symbols
6565
const kProvider = Symbol('kProvider');
@@ -97,7 +97,7 @@ class VirtualFileSystem {
9797
* @param {boolean} [options.virtualCwd] Whether to enable virtual working directory
9898
* @param {boolean} [options.overlay] Whether to enable overlay mode (only intercept existing files)
9999
*/
100-
constructor(providerOrOptions, options = {}) {
100+
constructor(providerOrOptions, options = kEmptyObject) {
101101
emitExperimentalWarning('VirtualFileSystem');
102102

103103
// Handle case where first arg is options object (no provider)
@@ -690,8 +690,7 @@ class VirtualFileSystem {
690690
}
691691

692692
this[kProvider].readFile(this.#toProviderPath(filePath), options)
693-
.then((data) => callback(null, data))
694-
.catch((err) => callback(err));
693+
.then((data) => callback(null, data), (err) => callback(err));
695694
}
696695

697696
/**
@@ -708,8 +707,7 @@ class VirtualFileSystem {
708707
}
709708

710709
this[kProvider].writeFile(this.#toProviderPath(filePath), data, options)
711-
.then(() => callback(null))
712-
.catch((err) => callback(err));
710+
.then(() => callback(null), (err) => callback(err));
713711
}
714712

715713
/**
@@ -725,8 +723,7 @@ class VirtualFileSystem {
725723
}
726724

727725
this[kProvider].stat(this.#toProviderPath(filePath), options)
728-
.then((stats) => callback(null, stats))
729-
.catch((err) => callback(err));
726+
.then((stats) => callback(null, stats), (err) => callback(err));
730727
}
731728

732729
/**
@@ -742,8 +739,7 @@ class VirtualFileSystem {
742739
}
743740

744741
this[kProvider].lstat(this.#toProviderPath(filePath), options)
745-
.then((stats) => callback(null, stats))
746-
.catch((err) => callback(err));
742+
.then((stats) => callback(null, stats), (err) => callback(err));
747743
}
748744

749745
/**
@@ -759,8 +755,7 @@ class VirtualFileSystem {
759755
}
760756

761757
this[kProvider].readdir(this.#toProviderPath(dirPath), options)
762-
.then((entries) => callback(null, entries))
763-
.catch((err) => callback(err));
758+
.then((entries) => callback(null, entries), (err) => callback(err));
764759
}
765760

766761
/**
@@ -776,8 +771,7 @@ class VirtualFileSystem {
776771
}
777772

778773
this[kProvider].realpath(this.#toProviderPath(filePath), options)
779-
.then((realPath) => callback(null, this.#toMountedPath(realPath)))
780-
.catch((err) => callback(err));
774+
.then((realPath) => callback(null, this.#toMountedPath(realPath)), (err) => callback(err));
781775
}
782776

783777
/**
@@ -793,8 +787,7 @@ class VirtualFileSystem {
793787
}
794788

795789
this[kProvider].readlink(this.#toProviderPath(linkPath), options)
796-
.then((target) => callback(null, target))
797-
.catch((err) => callback(err));
790+
.then((target) => callback(null, target), (err) => callback(err));
798791
}
799792

800793
/**
@@ -810,8 +803,7 @@ class VirtualFileSystem {
810803
}
811804

812805
this[kProvider].access(this.#toProviderPath(filePath), mode)
813-
.then(() => callback(null))
814-
.catch((err) => callback(err));
806+
.then(() => callback(null), (err) => callback(err));
815807
}
816808

817809
/**
@@ -836,8 +828,7 @@ class VirtualFileSystem {
836828
.then((handle) => {
837829
const fd = openVirtualFd(handle);
838830
callback(null, fd);
839-
})
840-
.catch((err) => callback(err));
831+
}, (err) => callback(err));
841832
}
842833

843834
/**
@@ -856,8 +847,7 @@ class VirtualFileSystem {
856847
.then(() => {
857848
closeVirtualFd(fd);
858849
callback(null);
859-
})
860-
.catch((err) => callback(err));
850+
}, (err) => callback(err));
861851
}
862852

863853
/**
@@ -877,8 +867,7 @@ class VirtualFileSystem {
877867
}
878868

879869
vfd.entry.read(buffer, offset, length, position)
880-
.then(({ bytesRead }) => callback(null, bytesRead, buffer))
881-
.catch((err) => callback(err));
870+
.then(({ bytesRead }) => callback(null, bytesRead, buffer), (err) => callback(err));
882871
}
883872

884873
/**
@@ -900,8 +889,7 @@ class VirtualFileSystem {
900889
}
901890

902891
vfd.entry.stat(options)
903-
.then((stats) => callback(null, stats))
904-
.catch((err) => callback(err));
892+
.then((stats) => callback(null, stats), (err) => callback(err));
905893
}
906894

907895
// ==================== Stream Operations ====================

lib/internal/vfs/module_hooks.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,17 @@ function normalizeVFSPath(inputPath) {
3333
return path.normalize(inputPath);
3434
}
3535
const { isURL, pathToFileURL, fileURLToPath, toPathIfFileURL, URL } = require('internal/url');
36-
const { kEmptyObject } = require('internal/util');
36+
const { getLazy, kEmptyObject } = require('internal/util');
3737
const { validateObject } = require('internal/validators');
3838
const { createENOENT } = require('internal/vfs/errors');
3939

40+
// Lazy-load modules to avoid circular dependencies during bootstrap
41+
const lazyFs = getLazy(() => require('fs'));
42+
const lazyFsPromises = getLazy(() => require('fs/promises'));
43+
const lazyModule = getLazy(
44+
() => require('internal/modules/cjs/loader').Module,
45+
);
46+
4047
// Registry of active VFS instances
4148
const activeVFSList = [];
4249

@@ -757,8 +764,10 @@ function resolveBareSpecifier(specifier, context, nextResolve) {
757764
}
758765

759766
/**
760-
* Convert a file path or file URL to a normalized file path.
761-
* @param {string} urlOrPath URL or path string
767+
* Convert a file URL string or path to a normalized file path.
768+
* Note: This differs from toPathIfFileURL which only handles URL objects,
769+
* not 'file:' strings that come from context.parentURL.
770+
* @param {string} urlOrPath URL string or path
762771
* @returns {string} Normalized file path
763772
*/
764773
function urlToPath(urlOrPath) {
@@ -861,9 +870,7 @@ function vfsLoadHook(url, context, nextLoad) {
861870
* are called, eliminating the need for monkeypatching.
862871
*/
863872
function installModuleHooks() {
864-
const Module = require('internal/modules/cjs/loader').Module;
865-
866-
Module.registerHooks({
873+
lazyModule().registerHooks({
867874
resolve: vfsResolveHook,
868875
load: vfsLoadHook,
869876
});
@@ -874,7 +881,7 @@ function installModuleHooks() {
874881
* These make fs.readFileSync('/vfs/path'), fs.statSync, etc. work for user code.
875882
*/
876883
function installFsPatches() {
877-
const fs = require('fs');
884+
const fs = lazyFs();
878885

879886
// Save originals
880887
originalReadFileSync = fs.readFileSync;
@@ -961,7 +968,7 @@ function installFsPatches() {
961968
};
962969

963970
// Hook fs/promises for async glob support
964-
const fsPromises = require('fs/promises');
971+
const fsPromises = lazyFsPromises();
965972

966973
// Override fs/promises.readdir (needed for async glob support)
967974
originalPromisesReaddir = fsPromises.readdir;
@@ -1065,8 +1072,6 @@ function installFsPatches() {
10651072

10661073
/**
10671074
* Install all VFS hooks: module loading hooks and fs patches.
1068-
* Note: fs and internal modules are required here (not at top level) to avoid
1069-
* circular dependencies during bootstrap. This module may be loaded early.
10701075
*/
10711076
function installHooks() {
10721077
if (hooksInstalled) {

0 commit comments

Comments
 (0)