8f9296c00d
This aligns the output with what npm outputs. Without this change, Next.js causes unwanted changes in package-lock.json. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [x] Make sure the linting passes by running `yarn lint`
102 lines
3.3 KiB
TypeScript
102 lines
3.3 KiB
TypeScript
import { promises } from 'fs'
|
|
import '../server/node-polyfill-fetch'
|
|
import * as Log from '../build/output/log'
|
|
import findUp from 'next/dist/compiled/find-up'
|
|
|
|
/**
|
|
* Attempts to patch npm package-lock.json when it
|
|
* fails to include optionalDependencies for other platforms
|
|
* this can occur when the package-lock is rebuilt from a current
|
|
* node_modules install instead of pulling fresh package data
|
|
*/
|
|
export async function patchIncorrectLockfile(dir: string) {
|
|
const lockfilePath = await findUp('package-lock.json', { cwd: dir })
|
|
|
|
if (!lockfilePath) {
|
|
// if no lockfile present there is no action to take
|
|
return
|
|
}
|
|
const content = await promises.readFile(lockfilePath, 'utf8')
|
|
const lockfileParsed = JSON.parse(content)
|
|
|
|
const foundSwcPkgs = new Set()
|
|
const nextPkg = lockfileParsed.packages?.['node_modules/next']
|
|
|
|
// if we don't find next in the package-lock we can't continue
|
|
if (!nextPkg) {
|
|
return
|
|
}
|
|
const nextVersion = nextPkg.version
|
|
const packageKeys = Object.keys(lockfileParsed.dependencies || {})
|
|
|
|
const expectedSwcPkgs = Object.keys(nextPkg?.optionalDependencies).filter(
|
|
(pkg) => pkg.startsWith('@next/swc-')
|
|
)
|
|
|
|
packageKeys.forEach((pkgKey) => {
|
|
const swcIndex = pkgKey.indexOf('@next/swc-')
|
|
if (swcIndex > -1) {
|
|
foundSwcPkgs.add(pkgKey.substring(swcIndex))
|
|
}
|
|
})
|
|
|
|
// if swc package keys are missing manually populate them
|
|
// so installs on different platforms can succeed
|
|
// user will need to run npm i after to ensure it's corrected
|
|
if (foundSwcPkgs.size !== expectedSwcPkgs.length) {
|
|
Log.warn(`Found lockfile missing swc dependencies, patching..`)
|
|
|
|
try {
|
|
// populate fields for each missing swc pkg
|
|
for (const pkg of expectedSwcPkgs) {
|
|
if (!foundSwcPkgs.has(pkg)) {
|
|
const res = await fetch(`https://registry.npmjs.org/${pkg}`)
|
|
|
|
if (!res.ok) {
|
|
throw new Error(
|
|
`Failed to fetch registry info for ${pkg}, got status ${res.status}`
|
|
)
|
|
}
|
|
const data = await res.json()
|
|
const version = data.versions[nextVersion]
|
|
|
|
if (!version) {
|
|
throw new Error(
|
|
`Failed to find matching version for ${pkg} at ${nextVersion}`
|
|
)
|
|
}
|
|
if (lockfileParsed.dependencies) {
|
|
lockfileParsed.dependencies[pkg] = {
|
|
version: nextVersion,
|
|
resolved: version.dist.tarball,
|
|
integrity: version.dist.integrity,
|
|
optional: true,
|
|
}
|
|
}
|
|
lockfileParsed.packages[`node_modules/${pkg}`] = {
|
|
version: nextVersion,
|
|
resolved: version.dist.tarball,
|
|
integrity: version.dist.integrity,
|
|
cpu: version.cpu,
|
|
optional: true,
|
|
os: version.os,
|
|
engines: version.engines,
|
|
}
|
|
}
|
|
}
|
|
|
|
await promises.writeFile(
|
|
lockfilePath,
|
|
`${JSON.stringify(lockfileParsed, null, 2)}\n`
|
|
)
|
|
Log.warn(
|
|
'Lockfile was successfully patched, please run "npm install" to ensure @next/swc dependencies are downloaded'
|
|
)
|
|
} catch (err) {
|
|
Log.error(
|
|
`Failed to patch lockfile, please try uninstalling and reinstalling next in this workspace`
|
|
)
|
|
console.error(err)
|
|
}
|
|
}
|
|
}
|