diff --git a/src/extract/resolve/resolve-amd.mjs b/src/extract/resolve/resolve-amd.mjs index 52f111137..b688a09a3 100644 --- a/src/extract/resolve/resolve-amd.mjs +++ b/src/extract/resolve/resolve-amd.mjs @@ -4,6 +4,14 @@ import { builtinModules } from "node:module"; import memoize from "lodash/memoize.js"; import pathToPosix from "../../utl/path-to-posix.mjs"; +// builtinModules does not expose all builtin modules for #reasons - +// see https://github.com/nodejs/node/issues/42785. In stead we could use +// isBuiltin, but that is not available in node 16.14, the lowest version +// of node dependency-cruiser currently supports. So we add the missing +// modules here. +// b.t.w. code is duplicated in resolve-cjs.mjs +const REALLY_BUILTIN_MODULES = builtinModules.concat(["test", "node:test"]); + const fileExists = memoize((pFile) => { try { accessSync(pFile, R_OK); @@ -16,7 +24,7 @@ const fileExists = memoize((pFile) => { function guessPath(pBaseDirectory, pFileDirectory, pStrippedModuleName) { return pathToPosix( - relative(pBaseDirectory, join(pFileDirectory, pStrippedModuleName)) + relative(pBaseDirectory, join(pFileDirectory, pStrippedModuleName)), ); } @@ -27,8 +35,8 @@ function guessLikelyPath(pBaseDirectory, pFileDirectory, pStrippedModuleName) { guessPath( pBaseDirectory, pFileDirectory, - `${pStrippedModuleName}${pExtension}` - ) + `${pStrippedModuleName}${pExtension}`, + ), ) .find(fileExists) || pStrippedModuleName ); @@ -37,7 +45,7 @@ function guessLikelyPath(pBaseDirectory, pFileDirectory, pStrippedModuleName) { export function resolveAMD( pStrippedModuleName, pBaseDirectory, - pFileDirectory + pFileDirectory, ) { // lookups: // - [x] could be relative in the end (implemented) @@ -48,15 +56,15 @@ export function resolveAMD( const lResolvedPath = guessLikelyPath( pBaseDirectory, pFileDirectory, - pStrippedModuleName + pStrippedModuleName, ); return { resolved: lResolvedPath, - coreModule: builtinModules.includes(pStrippedModuleName), + coreModule: REALLY_BUILTIN_MODULES.includes(pStrippedModuleName), followable: fileExists(lResolvedPath) && lResolvedPath.endsWith(".js"), couldNotResolve: - !builtinModules.includes(pStrippedModuleName) && + !REALLY_BUILTIN_MODULES.includes(pStrippedModuleName) && !fileExists(lResolvedPath), }; } diff --git a/src/extract/resolve/resolve-cjs.mjs b/src/extract/resolve/resolve-cjs.mjs index 42df4498c..424bac85e 100644 --- a/src/extract/resolve/resolve-cjs.mjs +++ b/src/extract/resolve/resolve-cjs.mjs @@ -4,27 +4,35 @@ import pathToPosix from "../../utl/path-to-posix.mjs"; import { isFollowable } from "./module-classifiers.mjs"; import { resolve } from "./resolve.mjs"; +// builtinModules does not expose all builtin modules for #reasons - +// see https://github.com/nodejs/node/issues/42785. In stead we could use +// isBuiltin, but that is not available in node 16.14, the lowest version +// of node dependency-cruiser currently supports. So we add the missing +// modules here. +// b.t.w. code is duplicated in resolve-amd.mjs +const REALLY_BUILTIN_MODULES = builtinModules.concat(["test", "node:test"]); + function addResolutionAttributes( pBaseDirectory, pModuleName, pFileDirectory, - pResolveOptions + pResolveOptions, ) { let lReturnValue = {}; - if (builtinModules.includes(pModuleName)) { + if (REALLY_BUILTIN_MODULES.includes(pModuleName)) { lReturnValue.coreModule = true; } else { try { lReturnValue.resolved = pathToPosix( relative( pBaseDirectory, - resolve(pModuleName, pFileDirectory, pResolveOptions) - ) + resolve(pModuleName, pFileDirectory, pResolveOptions), + ), ); lReturnValue.followable = isFollowable( lReturnValue.resolved, - pResolveOptions + pResolveOptions, ); } catch (pError) { lReturnValue.couldNotResolve = true; @@ -40,7 +48,7 @@ export default function resolveCommonJS( pStrippedModuleName, pBaseDirectory, pFileDirectory, - pResolveOptions + pResolveOptions, ) { return { resolved: pStrippedModuleName, @@ -51,7 +59,7 @@ export default function resolveCommonJS( pBaseDirectory, pStrippedModuleName, pFileDirectory, - pResolveOptions + pResolveOptions, ), }; } diff --git a/test/extract/resolve/index.general.spec.mjs b/test/extract/resolve/index.general.spec.mjs index 37a74336f..baaf2afa4 100644 --- a/test/extract/resolve/index.general.spec.mjs +++ b/test/extract/resolve/index.general.spec.mjs @@ -71,6 +71,46 @@ describe("[I] extract/resolve/index - general", () => { }); }); + it("resolves the 'test' core module as core module", () => { + expect( + resolve( + { + module: "test", + moduleSystem: "es6", + }, + join(__dirname, "__mocks__"), + join(__dirname, "__mocks__", "resolve"), + {}, + ), + ).to.deep.equal({ + coreModule: true, + couldNotResolve: false, + dependencyTypes: ["core"], + followable: false, + resolved: "test", + }); + }); + + it("resolves the 'node:test' core module as core module", () => { + expect( + resolve( + { + module: "node:test", + moduleSystem: "es6", + }, + join(__dirname, "__mocks__"), + join(__dirname, "__mocks__", "resolve"), + {}, + ), + ).to.deep.equal({ + coreModule: true, + couldNotResolve: false, + dependencyTypes: ["core"], + followable: false, + resolved: "node:test", + }); + }); + it("resolves to the moduleName input (and depType 'unknown') when not resolvable on disk", () => { expect( resolve(