Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't fail the build if @types/ packages appear to be missing #66127

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
}
})
})
Loading