mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 00:23:53 +00:00
feat(schema): remove some experimental options for v4 (#27132)
This commit is contained in:
parent
69860d952a
commit
5c34676159
@ -35,7 +35,7 @@ First, opt in to the nightly release channel [following these steps](/docs/guide
|
||||
|
||||
Then you can set your `compatibilityVersion` to match Nuxt 4 behavior:
|
||||
|
||||
```ts
|
||||
```ts twoslash [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
future: {
|
||||
compatibilityVersion: 4,
|
||||
@ -46,6 +46,7 @@ export default defineNuxtConfig({
|
||||
// app: 'app'
|
||||
// },
|
||||
// experimental: {
|
||||
// sharedPrerenderData: false,
|
||||
// compileTemplate: true,
|
||||
// templateUtils: true,
|
||||
// relativeWatchPaths: true,
|
||||
@ -136,7 +137,7 @@ nuxt.config.ts
|
||||
|
||||
However, migration is _not required_. If you wish to keep your current folder structure, Nuxt should auto-detect it. (If it does not, please raise an issue.) You can also force a v3 folder structure with the following configuration:
|
||||
|
||||
```ts
|
||||
```ts [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
// This reverts the new srcDir default from `app` back to your root directory
|
||||
srcDir: '.',
|
||||
@ -147,6 +148,47 @@ export default defineNuxtConfig({
|
||||
})
|
||||
```
|
||||
|
||||
#### Shared Prerender Data
|
||||
|
||||
🚦 **Impact Level**: Medium
|
||||
|
||||
##### What Changed
|
||||
|
||||
We enabled a previously experimental feature to share data from `useAsyncData` and `useFetch` calls, across different pages. See [original PR](https://github.com/nuxt/nuxt/pull/24894).
|
||||
|
||||
##### Reasons for Change
|
||||
|
||||
This feature automatically shares payload _data_ between pages that are prerendered. This can result in a significant performance improvement when prerendering sites that use `useAsyncData` or `useFetch` and fetch the same data in different pages.
|
||||
|
||||
For example, if your site requires a `useFetch` call for every page (for example, to get navigation data for a menu, or site settings from a CMS), this data would only be fetched once when prerendering the first page that uses it, and then cached for use when prerendering other pages.
|
||||
|
||||
##### Migration Steps
|
||||
|
||||
Make sure that any unique key of your data is always resolvable to the same data. For example, if you are using `useAsyncData` to fetch data related to a particular page, you should provide a key that uniquely matches that data. (`useFetch` should do this automatically for you.)
|
||||
|
||||
```ts [app/pages/test/[slug\\].vue]
|
||||
// This would be unsafe in a dynamic page (e.g. `[slug].vue`) because the route slug makes a difference
|
||||
// to the data fetched, but Nuxt can't know that because it's not reflected in the key.
|
||||
const route = useRoute()
|
||||
const { data } = await useAsyncData(async () => {
|
||||
return await $fetch(`/api/my-page/${route.params.slug}`)
|
||||
})
|
||||
// Instead, you should use a key that uniquely identifies the data fetched.
|
||||
const { data } = await useAsyncData(route.params.slug, async () => {
|
||||
return await $fetch(`/api/my-page/${route.params.slug}`)
|
||||
})
|
||||
```
|
||||
|
||||
Alternatively, you can disable this feature with:
|
||||
|
||||
```ts twoslash [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
experimental: {
|
||||
sharedPrerenderData: false
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### Shallow Data Reactivity in `useAsyncData` and `useFetch`
|
||||
|
||||
🚦 **Impact Level**: Minimal
|
||||
@ -171,7 +213,7 @@ In most cases, no migration steps are required, but if you rely on the reactivit
|
||||
+ const { data } = useFetch('/api/test', { deep: true })
|
||||
```
|
||||
1. You can change the default behavior on a project-wide basis (not recommended):
|
||||
```ts
|
||||
```ts twoslash [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
experimental: {
|
||||
defaults: {
|
||||
@ -270,6 +312,29 @@ const importSources = (sources: string | string[], { lazy = false } = {}) => {
|
||||
const importName = genSafeVariableName
|
||||
```
|
||||
|
||||
#### Removal of Experimental Features
|
||||
|
||||
🚦 **Impact Level**: Minimal
|
||||
|
||||
##### What Changed
|
||||
|
||||
Four experimental features are no longer configurable in Nuxt 4:
|
||||
|
||||
* `treeshakeClientOnly` will be `true` (default since v3.0)
|
||||
* `configSchema` will be `true` (default since v3.3)
|
||||
* `polyfillVueUseHead` will be `false` (default since v3.4)
|
||||
* `respectNoSSRHeader` will be `false` (default since v3.4)
|
||||
|
||||
##### Reasons for Change
|
||||
|
||||
These options have been set to their current values for some time and we do not have a reason to believe that they need to remain configurable.
|
||||
|
||||
##### Migration Steps
|
||||
|
||||
* `polyfillVueUseHead` is implementable in user-land with [this plugin](https://github.com/nuxt/nuxt/blob/f209158352b09d1986aa320e29ff36353b91c358/packages/nuxt/src/head/runtime/plugins/vueuse-head-polyfill.ts#L10-L11)
|
||||
|
||||
* `respectNoSSRHeader`is implementable in user-land with [server middleware](https://github.com/nuxt/nuxt/blob/c660b39447f0d5b8790c0826092638d321cd6821/packages/nuxt/src/core/runtime/nitro/no-ssr.ts#L8-L9)
|
||||
|
||||
## Nuxt 2 vs Nuxt 3
|
||||
|
||||
In the table below, there is a quick comparison between 3 versions of Nuxt:
|
||||
|
@ -386,6 +386,16 @@ This option allows exposing some route metadata defined in `definePageMeta` at b
|
||||
|
||||
This only works with static or strings/arrays rather than variables or conditional assignment. See [original issue](https://github.com/nuxt/nuxt/issues/24770) for more information and context.
|
||||
|
||||
<!-- You can disable this feature if it causes issues in your project.
|
||||
|
||||
```ts twoslash [nuxt.config.ts]
|
||||
export default defineNuxtConfig({
|
||||
experimental: {
|
||||
scanPageMeta: false
|
||||
}
|
||||
})
|
||||
``` -->
|
||||
|
||||
## cookieStore
|
||||
|
||||
Enables CookieStore support to listen for cookie updates (if supported by the browser) and refresh `useCookie` ref values.
|
||||
|
@ -136,8 +136,18 @@ export default defineUntypedSchema({
|
||||
/**
|
||||
* Tree shakes contents of client-only components from server bundle.
|
||||
* @see [Nuxt PR #5750](https://github.com/nuxt/framework/pull/5750)
|
||||
* @deprecated This option will no longer be configurable in Nuxt v4
|
||||
*/
|
||||
treeshakeClientOnly: true,
|
||||
treeshakeClientOnly: {
|
||||
async $resolve (val, get) {
|
||||
const isV4 = ((await get('future') as Record<string, unknown>).compatibilityVersion === 4)
|
||||
if (isV4 && val === false) {
|
||||
console.warn('Enabling `experimental.treeshakeClientOnly` in v4 compatibility mode as it will no longer be configurable in Nuxt v4.')
|
||||
return true
|
||||
}
|
||||
return val ?? true
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Emit `app:chunkError` hook when there is an error loading vite/webpack
|
||||
@ -246,19 +256,51 @@ export default defineUntypedSchema({
|
||||
/**
|
||||
* Config schema support
|
||||
* @see [Nuxt Issue #15592](https://github.com/nuxt/nuxt/issues/15592)
|
||||
* @deprecated This option will no longer be configurable in Nuxt v4
|
||||
*/
|
||||
configSchema: true,
|
||||
configSchema: {
|
||||
async $resolve (val, get) {
|
||||
const isV4 = ((await get('future') as Record<string, unknown>).compatibilityVersion === 4)
|
||||
if (isV4 && val === false) {
|
||||
console.warn('Enabling `experimental.configSchema` in v4 compatibility mode as it will no longer be configurable in Nuxt v4.')
|
||||
return true
|
||||
}
|
||||
return val ?? true
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether or not to add a compatibility layer for modules, plugins or user code relying on the old
|
||||
* `@vueuse/head` API.
|
||||
*
|
||||
* This can be disabled for most Nuxt sites to reduce the client-side bundle by ~0.5kb.
|
||||
* This is disabled to reduce the client-side bundle by ~0.5kb.
|
||||
* @deprecated This feature will be removed in Nuxt v4.
|
||||
*/
|
||||
polyfillVueUseHead: false,
|
||||
polyfillVueUseHead: {
|
||||
async $resolve (val, get) {
|
||||
const isV4 = ((await get('future') as Record<string, unknown>).compatibilityVersion === 4)
|
||||
if (isV4 && val === true) {
|
||||
console.warn('Disabling `experimental.polyfillVueUseHead` in v4 compatibility mode as it will no longer be configurable in Nuxt v4.')
|
||||
return false
|
||||
}
|
||||
return val ?? false
|
||||
},
|
||||
},
|
||||
|
||||
/** Allow disabling Nuxt SSR responses by setting the `x-nuxt-no-ssr` header. */
|
||||
respectNoSSRHeader: false,
|
||||
/**
|
||||
* Allow disabling Nuxt SSR responses by setting the `x-nuxt-no-ssr` header.
|
||||
* @deprecated This feature will be removed in Nuxt v4.
|
||||
*/
|
||||
respectNoSSRHeader: {
|
||||
async $resolve (val, get) {
|
||||
const isV4 = ((await get('future') as Record<string, unknown>).compatibilityVersion === 4)
|
||||
if (isV4 && val === true) {
|
||||
console.warn('Disabling `experimental.respectNoSSRHeader` in v4 compatibility mode as it will no longer be configurable in Nuxt v4.')
|
||||
return false
|
||||
}
|
||||
return val ?? false
|
||||
},
|
||||
},
|
||||
|
||||
/** Resolve `~`, `~~`, `@` and `@@` aliases located within layers with respect to their layer source and root directories. */
|
||||
localLayerAliases: true,
|
||||
|
@ -13,6 +13,7 @@ import type { NuxtIslandResponse } from '#app'
|
||||
|
||||
const isWebpack = process.env.TEST_BUILDER === 'webpack'
|
||||
const isTestingAppManifest = process.env.TEST_MANIFEST !== 'manifest-off'
|
||||
const isV4 = process.env.TEST_V4 === 'true'
|
||||
|
||||
await setup({
|
||||
rootDir: fileURLToPath(new URL('./fixtures/basic', import.meta.url)),
|
||||
@ -57,7 +58,14 @@ describe('server api', () => {
|
||||
|
||||
describe('route rules', () => {
|
||||
it('should enable spa mode', async () => {
|
||||
const { script, attrs } = parseData(await $fetch('/route-rules/spa'))
|
||||
const headHtml = await $fetch('/route-rules/spa')
|
||||
|
||||
// SPA should render appHead tags
|
||||
expect(headHtml).toContain('<meta name="description" content="Nuxt Fixture">')
|
||||
expect(headHtml).toContain('<meta charset="utf-8">')
|
||||
expect(headHtml).toContain('<meta name="viewport" content="width=1024, initial-scale=1">')
|
||||
|
||||
const { script, attrs } = parseData(headHtml)
|
||||
expect(script.serverRendered).toEqual(false)
|
||||
if (isRenderingJson) {
|
||||
expect(attrs['data-ssr']).toEqual('false')
|
||||
@ -876,7 +884,7 @@ describe('head tags', () => {
|
||||
expect(headHtml).toContain('<meta content="0;javascript:alert(1)">')
|
||||
})
|
||||
|
||||
it('SPA should render appHead tags', async () => {
|
||||
it.skipIf(isV4)('SPA should render appHead tags', async () => {
|
||||
const headHtml = await $fetch('/head', { headers: { 'x-nuxt-no-ssr': '1' } })
|
||||
|
||||
expect(headHtml).toContain('<meta name="description" content="Nuxt Fixture">')
|
||||
@ -884,7 +892,7 @@ describe('head tags', () => {
|
||||
expect(headHtml).toContain('<meta name="viewport" content="width=1024, initial-scale=1">')
|
||||
})
|
||||
|
||||
it('legacy vueuse/head works', async () => {
|
||||
it.skipIf(isV4)('legacy vueuse/head works', async () => {
|
||||
const headHtml = await $fetch('/vueuse-head')
|
||||
expect(headHtml).toContain('<title>using provides usehead and updateDOM - VueUse head polyfill test</title>')
|
||||
})
|
||||
@ -2187,7 +2195,6 @@ describe('component islands', () => {
|
||||
result.html = result.html.replace(/ data-island-uid="([^"]*)"/g, '')
|
||||
|
||||
if (isDev()) {
|
||||
result.head.link = result.head.link.filter(l => !l.href.includes('@nuxt+ui-templates'))
|
||||
const fixtureDir = normalize(fileURLToPath(new URL('./fixtures/basic', import.meta.url)))
|
||||
for (const link of result.head.link) {
|
||||
link.href = link.href.replace(fixtureDir, '/<rootDir>').replaceAll('//', '/')
|
||||
@ -2210,14 +2217,12 @@ describe('component islands', () => {
|
||||
}
|
||||
`)
|
||||
} else if (isDev() && !isWebpack) {
|
||||
// TODO: resolve dev bug triggered by earlier fetch of /vueuse-head page
|
||||
// https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/runtime/nitro/renderer.ts#L139
|
||||
result.head.link = result.head.link.filter(h => !h.href.includes('SharedComponent'))
|
||||
expect(result.head).toMatchInlineSnapshot(`
|
||||
{
|
||||
"link": [
|
||||
{
|
||||
"href": "/_nuxt/components/SharedComponent.vue?vue&type=style&index=0&scoped=3ee84738&lang.css",
|
||||
"key": "island-link",
|
||||
"rel": "stylesheet",
|
||||
},
|
||||
{
|
||||
"href": "/_nuxt/components/islands/PureComponent.vue?vue&type=style&index=0&scoped=c0c0cf89&lang.css",
|
||||
"key": "island-link",
|
||||
|
Loading…
Reference in New Issue
Block a user