Upgrade auf Version 9

Um auf Version 9 zu aktualisieren, führen Sie folgenden Befehl aus:

Terminal
npm i next@9
Terminal
yarn add next@9
Terminal
pnpm up next@9
Terminal
bun add next@9

Wichtig: Wenn Sie TypeScript verwenden, stellen Sie sicher, dass Sie auch @types/react und @types/react-dom auf die entsprechenden Versionen aktualisieren.

Überprüfen Sie Ihre Custom App-Datei (pages/_app.js)

Falls Sie zuvor das Beispiel für eine Custom <App> kopiert haben, können Sie möglicherweise Ihr getInitialProps entfernen.

Die Entfernung von getInitialProps aus pages/_app.js (wenn möglich) ist wichtig, um neue Next.js-Funktionen nutzen zu können!

Das folgende getInitialProps hat keine Funktion und kann entfernt werden:

class MyApp extends App {
  // Kann entfernt werden, hat keine Funktion!
  static async getInitialProps({ Component, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx)
    }

    return { pageProps }
  }

  render() {
    // ... etc
  }
}

Breaking Changes

@zeit/next-typescript ist nicht mehr notwendig

Next.js ignoriert nun die Verwendung von @zeit/next-typescript und warnt Sie, es zu entfernen. Bitte entfernen Sie dieses Plugin aus Ihrer next.config.js.

Entfernen Sie Referenzen auf @zeit/next-typescript/babel aus Ihrer benutzerdefinierten .babelrc (falls vorhanden).

Die Verwendung von fork-ts-checker-webpack-plugin sollte ebenfalls aus Ihrer next.config.js entfernt werden.

TypeScript-Definitionen werden nun mit dem next-Paket veröffentlicht, daher müssen Sie @types/next deinstallieren, da diese in Konflikt stehen würden.

Die folgenden Typen haben sich geändert:

Diese Liste wurde von der Community erstellt, um Ihnen beim Upgrade zu helfen. Falls Sie weitere Unterschiede finden, senden Sie bitte einen Pull-Request, um die Liste zu ergänzen.

Von:

import { NextContext } from 'next'
import { NextAppContext, DefaultAppIProps } from 'next/app'
import { NextDocumentContext, DefaultDocumentIProps } from 'next/document'

Zu:

import { NextPageContext } from 'next'
import { AppContext, AppInitialProps } from 'next/app'
import { DocumentContext, DocumentInitialProps } from 'next/document'

Der config-Schlüssel ist jetzt ein Export auf einer Seite

Sie dürfen keine benutzerdefinierte Variable namens config mehr von einer Seite exportieren (z.B. export { config } / export const config ...). Diese exportierte Variable wird nun verwendet, um seitenbezogene Next.js-Konfiguration wie Opt-in AMP und API-Route-Funktionen anzugeben.

Sie müssen einen nicht für Next.js bestimmten config-Export umbenennen.

next/dynamic rendert standardmäßig nicht mehr "loading..." während des Ladens

Dynamische Komponenten rendern standardmäßig nichts während des Ladens. Sie können dieses Verhalten weiterhin anpassen, indem Sie die loading-Eigenschaft setzen:

import dynamic from 'next/dynamic'

const DynamicComponentWithCustomLoading = dynamic(
  () => import('../components/hello2'),
  {
    loading: () => <p>Loading</p>,
  }
)

withAmp wurde zugunsten eines exportierten Konfigurationsobjekts entfernt

Next.js hat jetzt das Konzept der seitenbezogenen Konfiguration, daher wurde die withAmp-Higher-Order-Komponente aus Gründen der Konsistenz entfernt.

Diese Änderung kann automatisch migriert werden, indem Sie die folgenden Befehle im Stammverzeichnis Ihres Next.js-Projekts ausführen:

Terminal
curl -L https://github.com/vercel/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/withamp-to-config.js npx jscodeshift -t ./withamp-to-config.js pages/**/*.js

Um diese Migration manuell durchzuführen oder zu sehen, was der Codemod erzeugt, siehe unten:

Vorher

import { withAmp } from 'next/amp'

function Home() {
  return <h1>My AMP Page</h1>
}

export default withAmp(Home)
// oder
export default withAmp(Home, { hybrid: true })

Nachher

export default function Home() {
  return <h1>My AMP Page</h1>
}

export const config = {
  amp: true,
  // oder
  amp: 'hybrid',
}

next export exportiert Seiten nicht mehr als index.html

Zuvor führte der Export von pages/about.js zu out/about/index.html. Dieses Verhalten wurde geändert und erzeugt nun out/about.html.

Sie können zum vorherigen Verhalten zurückkehren, indem Sie eine next.config.js mit folgendem Inhalt erstellen:

next.config.js
module.exports = {
  trailingSlash: true,
}

pages/api/ wird anders behandelt

Seiten in pages/api/ werden nun als API-Routen betrachtet. Seiten in diesem Verzeichnis enthalten kein clientseitiges Bundle mehr.

Veraltete Funktionen

next/dynamic hat das Laden mehrerer Module gleichzeitig als veraltet markiert

Die Möglichkeit, mehrere Module gleichzeitig zu laden, wurde in next/dynamic als veraltet markiert, um näher an der React-Implementierung (React.lazy und Suspense) zu sein.

Die Aktualisierung von Code, der sich auf dieses Verhalten verlässt, ist relativ einfach! Wir haben ein Vorher/Nachher-Beispiel bereitgestellt, um Ihnen bei der Migration Ihrer Anwendung zu helfen:

Vorher

import dynamic from 'next/dynamic'

const HelloBundle = dynamic({
  modules: () => {
    const components = {
      Hello1: () => import('../components/hello1').then((m) => m.default),
      Hello2: () => import('../components/hello2').then((m) => m.default),
    }

    return components
  },
  render: (props, { Hello1, Hello2 }) => (
    <div>
      <h1>{props.title}</h1>
      <Hello1 />
      <Hello2 />
    </div>
  ),
})

function DynamicBundle() {
  return <HelloBundle title="Dynamic Bundle" />
}

export default DynamicBundle

Nachher

import dynamic from 'next/dynamic'

const Hello1 = dynamic(() => import('../components/hello1'))
const Hello2 = dynamic(() => import('../components/hello2'))

function HelloBundle({ title }) {
  return (
    <div>
      <h1>{title}</h1>
      <Hello1 />
      <Hello2 />
    </div>
  )
}

function DynamicBundle() {
  return <HelloBundle title="Dynamic Bundle" />
}

export default DynamicBundle