Improve error message for deprecated `experimental.dynamicIO` config (#92081)
### What?
Added a specific, actionable error message when users have
`experimental.dynamicIO` in their `next.config` file. Instead of the
generic "invalid experimental key" message, users now see that
`dynamicIO` has been replaced by `cacheComponents`, with a link to the
documentation.
### Why?
When `experimental.dynamicIO` was removed, users upgrading to newer
versions only saw a generic "Unrecognized key(s) in object: 'dynamicIO'"
warning without any guidance on what to use instead. This forces
developers to search through docs/changelogs to discover that
`cacheComponents` is the replacement. A clear migration message
eliminates this friction.
### How?
Added a case for `dynamicIO` in the `normalizeNextConfigZodErrors`
function in `packages/next/src/server/config.ts`, following the same
pattern used for `turbopackPersistentCaching` →
`turbopackFileSystemCache` migrations. When Zod reports `dynamicIO` as
an unrecognized key under `experimental`, the error is upgraded to a
fatal error with a message pointing to `cacheComponents` and linking to
the docs.
## PR checklist (Fixing a bug)
- Errors have a helpful link attached: links to
https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheComponents