Skip to content

Commit

Permalink
fix: make nearestPackageJson() work as Node's
Browse files Browse the repository at this point in the history
nearestPackageJson() stops at the first package.json it finds, even if it has no `type` entry.
  • Loading branch information
Septh committed Jul 29, 2024
1 parent 77d144f commit 5d099b1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 24 deletions.
27 changes: 13 additions & 14 deletions source/cjs-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,49 +13,48 @@ 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<string, NodeJS.ModuleType | Symbol>()
const pkgTypeCache = new Map<string, NodeJS.ModuleType | null>()
function nearestPackageType(file: string, defaultType: NodeJS.ModuleType): NodeJS.ModuleType {
for (
let current = path.dirname(file), previous: string | undefined = undefined;
previous !== current;
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
}

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)
}
Expand Down
19 changes: 9 additions & 10 deletions source/esm-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,34 @@ export const resolve: ResolveHook = async (specifier, context, nextResolve) => {
return result
}

const unknownType = Symbol()
const pkgTypeCache = new Map<string, NodeJS.ModuleType | symbol>()
const pkgTypeCache = new Map<string, NodeJS.ModuleType | null>()
async function nearestPackageType(file: string): Promise<NodeJS.ModuleType> {
for (
let current = path.dirname(file), previous: string | undefined = undefined;
previous !== current;
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
Expand Down

0 comments on commit 5d099b1

Please sign in to comment.