rsnext/packages/next/lib/get-package-version.ts
Kristoffer K 1c75bf789b
perf(next): use require.resolve instead of resolve (#19518)
**What's the problem this PR addresses?**

- ~~https://github.com/vercel/next.js/pull/18768 started to ncc babel and thus it's version of resolve which breaks PnP support~~
Babel replaced `resolve` with the builtin `require.resolve` and a polyfill for older node versions in https://github.com/babel/babel/pull/12439 which was upgraded in https://github.com/vercel/next.js/pull/20586
- `next` unnecessarily bundles the `resolve` package when `require.resolve` is builtin and can do the same job

**How did you fix it?**

- ~~Avoid running `resolve` through ncc~~
Added a test for https://github.com/vercel/next.js/issues/19334 (closes https://github.com/vercel/next.js/issues/19334)
- Replace `resolve` with `require.resolve`
2021-01-11 14:43:08 +00:00

62 lines
1.5 KiB
TypeScript

import { promises as fs } from 'fs'
import findUp from 'next/dist/compiled/find-up'
import JSON5 from 'next/dist/compiled/json5'
import * as path from 'path'
type PackageJsonDependencies = {
dependencies: Record<string, string>
devDependencies: Record<string, string>
}
let cachedDeps: PackageJsonDependencies
async function getDependencies({
cwd,
}: {
cwd: string
}): Promise<PackageJsonDependencies> {
if (cachedDeps) {
return cachedDeps
}
const configurationPath: string | undefined = await findUp('package.json', {
cwd,
})
if (!configurationPath) {
return (cachedDeps = { dependencies: {}, devDependencies: {} })
}
const content = await fs.readFile(configurationPath, 'utf-8')
const packageJson: any = JSON5.parse(content)
const { dependencies = {}, devDependencies = {} } = packageJson || {}
return (cachedDeps = { dependencies, devDependencies })
}
export async function getPackageVersion({
cwd,
name,
}: {
cwd: string
name: string
}): Promise<string | null> {
const { dependencies, devDependencies } = await getDependencies({ cwd })
if (!(dependencies[name] || devDependencies[name])) {
return null
}
const cwd2 =
cwd.endsWith(path.posix.sep) || cwd.endsWith(path.win32.sep)
? cwd
: `${cwd}/`
try {
const targetPath = require.resolve(`${name}/package.json`, {
paths: [cwd2],
})
const targetContent = await fs.readFile(targetPath, 'utf-8')
return JSON5.parse(targetContent).version ?? null
} catch {
return null
}
}