Skip to content

Commit

Permalink
Don't fail the build if @types/ packages appear to be missing (#66127)
Browse files Browse the repository at this point in the history
Co-authored-by: Alessio Gravili <alessio@gravili.de>
  • Loading branch information
eps1lon and AlessioGr committed May 23, 2024
1 parent 3a1d3f8 commit 59ce87e
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 12 deletions.
55 changes: 43 additions & 12 deletions packages/next/src/lib/verify-typescript-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { bold, cyan, red, yellow } from './picocolors'
import path from 'path'

import { hasNecessaryDependencies } from './has-necessary-dependencies'
import type { NecessaryDependencies } from './has-necessary-dependencies'
import type {
MissingDependency,
NecessaryDependencies,
} from './has-necessary-dependencies'
import semver from 'next/dist/compiled/semver'
import { CompileError } from './compile-error'
import * as log from '../build/output/log'
Expand Down Expand Up @@ -69,11 +72,37 @@ export async function verifyTypeScriptSetup({
requiredPackages
)

if (deps.missing?.length > 0) {
const missingTypeDeps: MissingDependency[] = []
const missingDepsExceptTypes: MissingDependency[] = []
for (const dep of deps.missing) {
if (dep.pkg.startsWith('@types/')) {
missingTypeDeps.push(dep)
} else {
missingDepsExceptTypes.push(dep)
}
}

// Just warn for potentially missing type deps.
// TODO: Fix false-positive in `hasNecessaryDependencies` when `overrides` are used in package managers
if (missingTypeDeps.length > 0) {
console.log(
bold(
yellow(
`It looks like you're trying to use TypeScript but do not have the required type package(s) installed.`
)
) +
'\n' +
'This may be a bug in Next.js. Please file an issue.\n' +
'Make sure the following type packages are installed:\n' +
missingTypeDeps.map((dep) => ` ${cyan(dep.pkg)}`).join('\n')
)
}

if (missingDepsExceptTypes.length > 0) {
if (isCI) {
// we don't attempt auto install in CI to avoid side-effects
// and instead log the error for installing needed packages
missingDepsError(dir, deps.missing)
missingDepsError(dir, missingDepsExceptTypes)
}
console.log(
bold(
Expand All @@ -91,16 +120,18 @@ export async function verifyTypeScriptSetup({
) +
'\n'
)
await installDependencies(dir, deps.missing, true).catch((err) => {
if (err && typeof err === 'object' && 'command' in err) {
console.error(
`Failed to install required TypeScript dependencies, please install them manually to continue:\n` +
(err as any).command +
'\n'
)
await installDependencies(dir, missingDepsExceptTypes, true).catch(
(err) => {
if (err && typeof err === 'object' && 'command' in err) {
console.error(
`Failed to install required TypeScript dependencies, please install them manually to continue:\n` +
(err as any).command +
'\n'
)
}
throw err
}
throw err
})
)
deps = await hasNecessaryDependencies(dir, requiredPackages)
}

Expand Down
47 changes: 47 additions & 0 deletions test/production/ci-missing-typescript-deps/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,51 @@ describe('ci-missing-typescript-deps', () => {
await next.destroy()
}
})

it('should not throw an error if beta version of @types/react and @types/react-dom is installed', async () => {
const next = await createNext({
files: {
'pages/index.tsx': `
export default function Page() {
return <p>hello world</p>
}
`,
},
env: {
CI: '1',
},
skipStart: true,
dependencies: {
'@types/react': 'npm:types-react@beta',
'@types/react-dom': 'npm:types-react-dom@beta',
},
packageJson: {
overrides: {
'@types/react': 'npm:types-react@beta',
'@types/react-dom': 'npm:types-react-dom@beta',
},
pnpm: {
overrides: {
'@types/react': 'npm:types-react@beta',
'@types/react-dom': 'npm:types-react-dom@beta',
},
},
},
})
try {
const nextBuild = await next.build()
// build doesn't fail because types/ may not be installed.
expect(nextBuild.cliOutput.split('\n')).toEqual(
expect.arrayContaining([
'This may be a bug in Next.js. Please file an issue.',
'Make sure the following type packages are installed:',
// In cyan color but this changes between CI and local.
// TODO: Use picocolors in tests to ensure we can test local and CI.
expect.stringContaining('@types/react'),
])
)
} finally {
await next.destroy()
}
})
})

0 comments on commit 59ce87e

Please sign in to comment.