Skip to content

Commit 1c78689

Browse files
committed
cjs/loader.js WIP
1 parent 2cadb5e commit 1c78689

File tree

1 file changed

+78
-13
lines changed

1 file changed

+78
-13
lines changed

lib/internal/modules/cjs/loader.js

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ let requireDepth = 0;
155155
let isPreloading = false;
156156
let statCache = null;
157157

158+
/**
159+
* Our internal implementation of `require`.
160+
* @param {Module} module Parent module of what is being required
161+
* @param {string} id Specifier of the child module being imported
162+
*/
158163
function internalRequire(module, id) {
159164
validateString(id, 'id');
160165
if (id === '') {
@@ -169,6 +174,10 @@ function internalRequire(module, id) {
169174
}
170175
}
171176

177+
/**
178+
* Get a path's properties, using an in-memory cache to minimize lookups.
179+
* @param {string} filename Absolute path to the file
180+
*/
172181
function stat(filename) {
173182
filename = path.toNamespacedPath(filename);
174183
if (statCache !== null) {
@@ -195,24 +204,45 @@ ObjectDefineProperty(Module, '_stat', {
195204
configurable: true,
196205
});
197206

207+
/**
208+
* Update the parent's children array with the child module.
209+
* @param {Module} parent Module requiring the children
210+
* @param {Module} child Module being required
211+
* @param {boolean} scan Add the child to the parent's children if not already present
212+
*/
198213
function updateChildren(parent, child, scan) {
199214
const children = parent?.children;
200215
if (children && !(scan && ArrayPrototypeIncludes(children, child))) { ArrayPrototypePush(children, child); }
201216
}
202217

218+
/**
219+
* Tell the watch mode that a module was required.
220+
* @param {string} filename Absolute path of the module
221+
*/
203222
function reportModuleToWatchMode(filename) {
204223
if (shouldReportRequiredModules() && process.send) {
205224
process.send({ 'watch:require': [filename] });
206225
}
207226
}
208227

228+
/**
229+
* Tell the watch mode that a module was not found.
230+
* @param {string} basePath The absolute path that errored
231+
* @param {string[]} extensions The extensions that were tried
232+
*/
209233
function reportModuleNotFoundToWatchMode(basePath, extensions) {
210234
if (shouldReportRequiredModules() && process.send) {
211235
process.send({ 'watch:require': ArrayPrototypeMap(extensions, (ext) => path.resolve(`${basePath}${ext}`)) });
212236
}
213237
}
214238

239+
/** @type {Map<Module, Module>} */
215240
const moduleParentCache = new SafeWeakMap();
241+
/**
242+
* Create a new module instance.
243+
* @param {string} id
244+
* @param {Module} parent
245+
*/
216246
function Module(id = '', parent) {
217247
this.id = id;
218248
this.path = path.dirname(id);
@@ -235,16 +265,24 @@ function Module(id = '', parent) {
235265
this[require_private_symbol] = internalRequire;
236266
}
237267

268+
/** @type {Record<string, Module>} */
238269
Module._cache = { __proto__: null };
270+
/** @type {Record<string, string>} */
239271
Module._pathCache = { __proto__: null };
272+
/** @type {Record<string, (module: Module, filename: string) => void>} */
240273
Module._extensions = { __proto__: null };
274+
/** @type {string[]} */
241275
let modulePaths = [];
276+
/** @type {string[]} */
242277
Module.globalPaths = [];
243278

244279
let patched = false;
245280

246-
// eslint-disable-next-line func-style
247-
let wrap = function(script) {
281+
/**
282+
* Add the CommonJS wrapper around a module's source code.
283+
* @param {string} script Module source code
284+
*/
285+
let wrap = function(script) { // eslint-disable-line func-style
248286
return Module.wrapper[0] + script + Module.wrapper[1];
249287
};
250288

@@ -295,10 +333,17 @@ const isPreloadingDesc = { get() { return isPreloading; } };
295333
ObjectDefineProperty(Module.prototype, 'isPreloading', isPreloadingDesc);
296334
ObjectDefineProperty(BuiltinModule.prototype, 'isPreloading', isPreloadingDesc);
297335

336+
/**
337+
* Get the parent of the current module from our cache.
338+
*/
298339
function getModuleParent() {
299340
return moduleParentCache.get(this);
300341
}
301342

343+
/**
344+
* Set the parent of the current module in our cache.
345+
* @param {Module} value
346+
*/
302347
function setModuleParent(value) {
303348
moduleParentCache.set(this, value);
304349
}
@@ -325,7 +370,10 @@ ObjectDefineProperty(Module.prototype, 'parent', {
325370
Module._debug = pendingDeprecate(debug, 'Module._debug is deprecated.', 'DEP0077');
326371
Module.isBuiltin = BuiltinModule.isBuiltin;
327372

328-
// This function is called during pre-execution, before any user code is run.
373+
/**
374+
* Prepare to run CommonJS code.
375+
* This function is called during pre-execution, before any user code is run.
376+
*/
329377
function initializeCJS() {
330378
// This need to be done at runtime in case --expose-internals is set.
331379
const builtinModules = BuiltinModule.getCanBeRequiredByUsersWithoutSchemeList();
@@ -373,6 +421,11 @@ ObjectDefineProperty(Module, '_readPackage', {
373421
configurable: true,
374422
});
375423

424+
/**
425+
* Get the nearest parent package.json file from a given path.
426+
* Return the package.json data and the path to the package.json file, or false.
427+
* @param {string} checkPath The path to start searching from.
428+
*/
376429
function readPackageScope(checkPath) {
377430
const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, sep);
378431
let separatorIndex;
@@ -397,6 +450,13 @@ function readPackageScope(checkPath) {
397450
return false;
398451
}
399452

453+
/**
454+
* Try to load a specifier as a package.
455+
* @param {string} requestPath The path to what we are trying to load
456+
* @param {string[]} exts File extensions to try appending in order to resolve the file
457+
* @param {boolean} isMain Whether the file is the main entry point of the app
458+
* @param {string} originalPath The specifier passed to `require`
459+
*/
400460
function tryPackage(requestPath, exts, isMain, originalPath) {
401461
const pkg = _readPackage(requestPath).main;
402462

@@ -553,9 +613,10 @@ function resolveExports(nmPath, request) {
553613
}
554614

555615
/**
556-
* @param {string} request a relative or absolute file path
557-
* @param {Array<string>} paths file system directories to search as file paths
558-
* @param {boolean} isMain if the request is the main app entry point
616+
* Get the absolute path to a module.
617+
* @param {string} request Relative or absolute file path
618+
* @param {Array<string>} paths Folders to search as file paths
619+
* @param {boolean} isMain Whether the request is the main app entry point
559620
* @returns {string | false}
560621
*/
561622
Module._findPath = function(request, paths, isMain) {
@@ -851,13 +912,17 @@ function getExportsForCircularRequire(module) {
851912
return module.exports;
852913
}
853914

854-
// Check the cache for the requested file.
855-
// 1. If a module already exists in the cache: return its exports object.
856-
// 2. If the module is native: call
857-
// `BuiltinModule.prototype.compileForPublicLoader()` and return the exports.
858-
// 3. Otherwise, create a new module for the file and save it to the cache.
859-
// Then have it load the file contents before returning its exports
860-
// object.
915+
/**
916+
* Load a module from cache if it exists, otherwise create a new module instance.
917+
* 1. If a module already exists in the cache: return its exports object.
918+
* 2. If the module is native: call
919+
* `BuiltinModule.prototype.compileForPublicLoader()` and return the exports.
920+
* 3. Otherwise, create a new module for the file and save it to the cache.
921+
* Then have it load the file contents before returning its exports object.
922+
* @param {string} request Specifier of module to load via `require`
923+
* @param {string} parent Absolute path of the module importing the child
924+
* @param {boolean} isMain Whether the module is the main entry point
925+
*/
861926
Module._load = function(request, parent, isMain) {
862927
let relResolveCacheIdentifier;
863928
if (parent) {

0 commit comments

Comments
 (0)