feat(nuxt): allow chunk error or manifest update -> reload (#28160)

This commit is contained in:
Nils 2024-11-02 22:28:04 +01:00 committed by GitHub
parent be892629eb
commit f788b0dfcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 5 deletions

View File

@ -59,14 +59,16 @@ This feature will likely be removed in a near future.
## emitRouteChunkError ## emitRouteChunkError
Emits `app:chunkError` hook when there is an error loading vite/webpack chunks. Default behavior is to perform a hard reload of the new route when a chunk fails to load. Emits `app:chunkError` hook when there is an error loading vite/webpack chunks. Default behavior is to perform a reload of the new route on navigation to a new route when a chunk fails to load.
If you set this to `'automatic-immediate'` Nuxt will reload the current route immediatly, instead of waiting for a navigation. This is useful for chunk errors that are not triggered by navigation, e.g., when your Nuxt app fails to load a [lazy component](/docs/guide/directory-structure/components#dynamic-imports). A potential downside of this behavior is undesired reloads, e.g., when your app does not need the chunk that caused the error.
You can disable automatic handling by setting this to `false`, or handle chunk errors manually by setting it to `manual`. You can disable automatic handling by setting this to `false`, or handle chunk errors manually by setting it to `manual`.
```ts twoslash [nuxt.config.ts] ```ts twoslash [nuxt.config.ts]
export default defineNuxtConfig({ export default defineNuxtConfig({
experimental: { experimental: {
emitRouteChunkError: 'automatic' // or 'manual' or false emitRouteChunkError: 'automatic' // or 'automatic-immediate', 'manual' or false
} }
}) })
``` ```

View File

@ -0,0 +1,23 @@
import { defineNuxtPlugin } from '../nuxt'
import { reloadNuxtApp } from '../composables/chunk'
import { addRouteMiddleware } from '../composables/router'
const reloadNuxtApp_ = (path: string) => { reloadNuxtApp({ persistState: true, path }) }
// See https://github.com/nuxt/nuxt/issues/23612 for more context
export default defineNuxtPlugin({
name: 'nuxt:chunk-reload-immediate',
setup (nuxtApp) {
// Remember `to.path` when navigating to a new path: A `chunkError` may occur during navigation, we then want to then reload at `to.path`
let currentlyNavigationTo: null | string = null
addRouteMiddleware((to) => {
currentlyNavigationTo = to.path
})
// Reload when a `chunkError` is thrown
nuxtApp.hook('app:chunkError', () => reloadNuxtApp_(currentlyNavigationTo ?? nuxtApp._route.path))
// Reload when the app manifest updates
nuxtApp.hook('app:manifest:update', () => reloadNuxtApp_(nuxtApp._route.path))
},
})

View File

@ -576,6 +576,11 @@ async function initNuxt (nuxt: Nuxt) {
if (nuxt.options.experimental.emitRouteChunkError === 'automatic') { if (nuxt.options.experimental.emitRouteChunkError === 'automatic') {
addPlugin(resolve(nuxt.options.appDir, 'plugins/chunk-reload.client')) addPlugin(resolve(nuxt.options.appDir, 'plugins/chunk-reload.client'))
} }
// Add experimental immediate page reload support
if (nuxt.options.experimental.emitRouteChunkError === 'automatic-immediate') {
addPlugin(resolve(nuxt.options.appDir, 'plugins/chunk-reload-immediate.client'))
}
// Add experimental session restoration support // Add experimental session restoration support
if (nuxt.options.experimental.restoreState) { if (nuxt.options.experimental.restoreState) {
addPlugin(resolve(nuxt.options.appDir, 'plugins/restore-state.client')) addPlugin(resolve(nuxt.options.appDir, 'plugins/restore-state.client'))

View File

@ -116,13 +116,16 @@ export default defineUntypedSchema({
* Emit `app:chunkError` hook when there is an error loading vite/webpack * Emit `app:chunkError` hook when there is an error loading vite/webpack
* chunks. * chunks.
* *
* By default, Nuxt will also perform a hard reload of the new route * By default, Nuxt will also perform a reload of the new route
* when a chunk fails to load when navigating to a new route. * when a chunk fails to load when navigating to a new route (`automatic`).
*
* Setting `automatic-immediate` will lead Nuxt to perform a reload of the current route
* right when a chunk fails to load (instead of waiting for navigation).
* *
* You can disable automatic handling by setting this to `false`, or handle * You can disable automatic handling by setting this to `false`, or handle
* chunk errors manually by setting it to `manual`. * chunk errors manually by setting it to `manual`.
* @see [Nuxt PR #19038](https://github.com/nuxt/nuxt/pull/19038) * @see [Nuxt PR #19038](https://github.com/nuxt/nuxt/pull/19038)
* @type {false | 'manual' | 'automatic'} * @type {false | 'manual' | 'automatic' | 'automatic-immediate'}
*/ */
emitRouteChunkError: { emitRouteChunkError: {
$resolve: (val) => { $resolve: (val) => {