From 5d099b114f6af8f4dd31bae3d474d7d8d80bfbeb Mon Sep 17 00:00:00 2001 From: Stephan Schreiber Date: Mon, 29 Jul 2024 13:19:24 +0200 Subject: [PATCH] fix: make nearestPackageJson() work as Node's nearestPackageJson() stops at the first package.json it finds, even if it has no `type` entry. --- source/cjs-hooks.ts | 27 +++++++++++++-------------- source/esm-hooks.ts | 19 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/source/cjs-hooks.ts b/source/cjs-hooks.ts index 36c23f6..e6cbbaa 100644 --- a/source/cjs-hooks.ts +++ b/source/cjs-hooks.ts @@ -13,13 +13,12 @@ function transpile(m: Module, format: NodeJS.ModuleType, filePath: string) { // This infers a very small performance penalty when transpile() is called // for the fist time, but we'll live with it. const { transform } = require('./transform.cjs') as typeof import('./transform.cjs') - const source = readFileSync(filePath.replace(jsExtRx, '.$1ts')).toString() + const source = readFileSync(filePath).toString() const code = transform(source, format, path.basename(filePath)) return m._compile(code, filePath) } -const unknownType = Symbol() -const pkgTypeCache = new Map() +const pkgTypeCache = new Map() function nearestPackageType(file: string, defaultType: NodeJS.ModuleType): NodeJS.ModuleType { for ( let current = path.dirname(file), previous: string | undefined = undefined; @@ -27,27 +26,27 @@ function nearestPackageType(file: string, defaultType: NodeJS.ModuleType): NodeJ previous = current, current = path.dirname(current) ) { const pkgFile = path.join(current, 'package.json') - let format = pkgTypeCache.get(pkgFile) - if (!format) { + let cached = pkgTypeCache.get(pkgFile) + if (cached === undefined) { try { - const data = readFileSync(pkgFile, 'utf-8') - const { type } = JSON.parse(data) as PackageJson - format = type === 'module' || type ==='commonjs' + const data = readFileSync(pkgFile) + const { type } = JSON.parse(data.toString()) as PackageJson + cached = type === 'module' || type ==='commonjs' ? type - : unknownType + : defaultType } catch(err) { const { code } = err as NodeJS.ErrnoException if (code !== 'ENOENT') console.error(err) - format = unknownType + cached = null } - pkgTypeCache.set(pkgFile, format) + pkgTypeCache.set(pkgFile, cached) } - if (typeof format === 'string') - return format + if (typeof cached === 'string') + return cached } return defaultType @@ -55,7 +54,7 @@ function nearestPackageType(file: string, defaultType: NodeJS.ModuleType): NodeJ export function install_cjs_hooks(defaultType: NodeJS.ModuleType) { const { _resolveFilename } = Module - Module._resolveFilename = function(request, ...otherArgs) { + Module._resolveFilename = function _resolveFilenamePatch(request, ...otherArgs) { try { return _resolveFilename.call(undefined, request, ...otherArgs) } diff --git a/source/esm-hooks.ts b/source/esm-hooks.ts index 8e37756..9c79146 100644 --- a/source/esm-hooks.ts +++ b/source/esm-hooks.ts @@ -44,8 +44,7 @@ export const resolve: ResolveHook = async (specifier, context, nextResolve) => { return result } -const unknownType = Symbol() -const pkgTypeCache = new Map() +const pkgTypeCache = new Map() async function nearestPackageType(file: string): Promise { for ( let current = path.dirname(file), previous: string | undefined = undefined; @@ -53,26 +52,26 @@ async function nearestPackageType(file: string): Promise { previous = current, current = path.dirname(current) ) { const pkgFile = path.join(current, 'package.json') - let format = pkgTypeCache.get(pkgFile) - if (!format) { - format = await readFile(pkgFile) + let cached = pkgTypeCache.get(pkgFile) + if (cached === undefined) { + cached = await readFile(pkgFile) .then(data => { const { type } = JSON.parse(data.toString()) as PackageJson return type === 'module' || type === 'commonjs' ? type - : unknownType + : hookData.defaultModuleType }) .catch(err => { const { code } = err as NodeJS.ErrnoException if (code !== 'ENOENT') console.error(err) - return unknownType + return null }) - pkgTypeCache.set(pkgFile, format) + pkgTypeCache.set(pkgFile, cached) } - if (typeof format === 'string') - return format + if (typeof cached === 'string') + return cached } return hookData.defaultModuleType