mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
a0c6a6140e
### What?
Flips the default `experimental.instantInsights.validationLevel` from
`'manual-warning'` to `'warning'` so Cache Components apps get
instant-navigation validation across all pages by default.
### Why?
`'manual-warning'` only validates pages that explicitly export
`unstable_instant`, so apps see nothing unless they opt in. `'warning'`
is what users have been turning on manually to actually see the feature
(`v0`, `vercel-site`).
### Test coverage
- Unit: `instant-config-normalization.test.ts` pins the framework
default at `'warning'`.
- Integration: new `instant-validation-level-default/` fixture (no
`instantInsights` in config) asserts implicit dev validation fires, and
that build is unaffected.
### Collateral test fixtures
Tests whose intent is unrelated to instant validation
(router-autoscroll, owner-stack, hmr-iframe, next-image,
server-source-maps, etc.) now hit new redboxes/console warnings because
their fixtures incidentally use dynamic data. Each opts out with
`experimental: { instantInsights: { validationLevel: 'manual-warning' }
}` in `next.config`.
### Open question
With no `'off'` / `'info'` tier today, silencing Insights after this
change requires setting `validationLevel: 'manual-warning'`. Is that
acceptable? Should we inform of this anywhere?
<!-- NEXT_JS_LLM_PR -->
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import path from 'path'
|
|
import loadConfig from 'next/dist/server/config'
|
|
import { PHASE_PRODUCTION_SERVER } from 'next/constants'
|
|
|
|
// `loadConfig` caches its result keyed on `dir` + a boolean "hasCustomConfig".
|
|
// Each test uses a unique subdirectory so the cache doesn't bleed between
|
|
// cases. The subdirectory doesn't need to exist — only the string matters
|
|
// for the cache key, and `loadEnvConfig` tolerates missing dirs.
|
|
function uniqueDir(tag: string) {
|
|
return path.join(__dirname, `__instant_normalization_${tag}__`)
|
|
}
|
|
|
|
// Covers the `finalizeConfig` step in loadConfig: resolving
|
|
// `experimental.instantInsights.validationLevel` to a concrete value in
|
|
// one place so consumers don't each need to know the current framework default.
|
|
describe('experimental.instantInsights validationLevel normalization', () => {
|
|
it('defaults to warning when the instantInsights config is absent', async () => {
|
|
const config = await loadConfig(
|
|
PHASE_PRODUCTION_SERVER,
|
|
uniqueDir('absent'),
|
|
{
|
|
customConfig: {},
|
|
}
|
|
)
|
|
expect(config.experimental.instantInsights).toEqual({
|
|
validationLevel: 'warning',
|
|
})
|
|
})
|
|
|
|
it('defaults to warning when experimental.instantInsights is an empty object', async () => {
|
|
const config = await loadConfig(
|
|
PHASE_PRODUCTION_SERVER,
|
|
uniqueDir('empty'),
|
|
{
|
|
customConfig: { experimental: { instantInsights: {} } },
|
|
}
|
|
)
|
|
expect(config.experimental.instantInsights).toEqual({
|
|
validationLevel: 'warning',
|
|
})
|
|
})
|
|
|
|
it.each([
|
|
'warning',
|
|
'manual-warning',
|
|
'experimental-error',
|
|
'experimental-manual-error',
|
|
] as const)('preserves explicit validationLevel: %s', async (level) => {
|
|
const config = await loadConfig(
|
|
PHASE_PRODUCTION_SERVER,
|
|
uniqueDir(`level-${level}`),
|
|
{
|
|
customConfig: {
|
|
experimental: { instantInsights: { validationLevel: level } },
|
|
},
|
|
}
|
|
)
|
|
expect(config.experimental.instantInsights).toEqual({
|
|
validationLevel: level,
|
|
})
|
|
})
|
|
})
|