Skip to content

Commit

Permalink
[build] validate the exported config values (#38370)
Browse files Browse the repository at this point in the history
Right now if people will accidentally export a typo like `runtime: 'experimental-egde'` we will fail silently.
This commit ensures we will throw and fail loudly when such typos occur.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
  • Loading branch information
Schniz committed Jul 6, 2022
1 parent 20c1079 commit 56e760a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 1 deletion.
20 changes: 19 additions & 1 deletion packages/next/build/analysis/get-page-static-info.ts
@@ -1,4 +1,4 @@
import type { ServerRuntime } from '../../server/config-shared'
import { isServerRuntime, ServerRuntime } from '../../server/config-shared'
import type { NextConfig } from '../../server/config-shared'
import { tryToExtractExportedConstValue } from './extract-const-value'
import { escapeStringRegexp } from '../../shared/lib/escape-regexp'
Expand Down Expand Up @@ -40,6 +40,24 @@ export async function getPageStaticInfo(params: {
const { ssg, ssr } = checkExports(swcAST)
const config = tryToExtractExportedConstValue(swcAST, 'config') || {}

if (
typeof config.runtime !== 'string' &&
typeof config.runtime !== 'undefined'
) {
throw new Error(`Provided runtime `)
} else if (!isServerRuntime(config.runtime)) {
const options = Object.values(SERVER_RUNTIME).join(', ')
if (typeof config.runtime !== 'string') {
throw new Error(
`The \`runtime\` config must be a string. Please leave it empty or choose one of: ${options}`
)
} else {
throw new Error(
`Provided runtime "${config.runtime}" is not supported. Please leave it empty or choose one of: ${options}`
)
}
}

let runtime =
SERVER_RUNTIME.edge === config?.runtime
? SERVER_RUNTIME.edge
Expand Down
6 changes: 6 additions & 0 deletions packages/next/server/config-shared.ts
Expand Up @@ -561,3 +561,9 @@ export async function normalizeConfig(phase: string, config: any) {
// Support `new Promise` and `async () =>` as return values of the config export
return await config
}

export function isServerRuntime(value?: string): value is ServerRuntime {
return (
value === undefined || value === 'nodejs' || value === 'experimental-edge'
)
}
@@ -0,0 +1,7 @@
export default function Page() {
return <p>hello world</p>
}

export const config = {
runtime: 'something-odd',
}
18 changes: 18 additions & 0 deletions test/production/exported-runtimes-value-validation/index.test.ts
@@ -0,0 +1,18 @@
import { nextBuild } from 'next-test-utils'
import path from 'path'

describe('Exported runtimes value validation', () => {
test('fails to build on malformed input', async () => {
const result = await nextBuild(
path.resolve(__dirname, './app'),
undefined,
{ stdout: true, stderr: true }
)
expect(result).toMatchObject({
code: 1,
stderr: expect.stringContaining(
`Provided runtime "something-odd" is not supported.`
),
})
})
})

0 comments on commit 56e760a

Please sign in to comment.