Menu

Codemods

Codemods sind Transformationen, die programmgesteuert auf Ihrer Codebasis ausgeführt werden. Dies ermöglicht es, eine große Anzahl von Änderungen programmgesteuert anzuwenden, ohne jede Datei manuell durchgehen zu müssen.

Next.js bietet Codemod-Transformationen, um Ihre Next.js-Codebasis zu aktualisieren, wenn eine API aktualisiert oder als veraltet markiert wird.

Verwendung

Navigieren Sie in Ihrem Terminal in den Projektordner und führen Sie dann aus:

Terminal
npx @next/codemod <transform> <path>

Ersetzen Sie <transform> und <path> durch die entsprechenden Werte.

  • transform - Name der Transformation
  • path - Dateien oder Verzeichnis, die transformiert werden sollen
  • --dry Führt einen Testlauf durch, es wird kein Code bearbeitet
  • --print Zeigt die geänderte Ausgabe zum Vergleich an

Codemods

15.0

Transformieren des App Router Route Segment Config runtime-Wertes von experimental-edge zu edge

app-dir-runtime-config-experimental-edge

Hinweis: Dieser Codemod ist spezifisch für den App Router.

Terminal
npx @next/codemod@latest app-dir-runtime-config-experimental-edge .

Dieser Codemod transformiert den Route Segment Config runtime-Wert experimental-edge zu edge.

Beispielsweise:

export const runtime = 'experimental-edge'

Wird transformiert zu:

export const runtime = 'edge'

Migration zu asynchronen dynamischen APIs

APIs, die sich für dynamisches Rendering entschieden haben und zuvor synchronen Zugriff unterstützten, sind jetzt asynchron. Weitere Informationen zu dieser Breaking Change finden Sie im Upgrade-Leitfaden.

next-async-request-api
Terminal
npx @next/codemod@latest next-async-request-api .

Dieser Codemod transformiert dynamische APIs (cookies(), headers() und draftMode() aus next/headers), die jetzt asynchron sind, damit sie korrekt abgewartet oder mit React.use() umschlossen werden. Wenn eine automatische Migration nicht möglich ist, fügt der Codemod entweder einen Typumwandlung hinzu (bei einer TypeScript-Datei) oder einen Kommentar, um den Benutzer zu informieren, dass eine manuelle Überprüfung und Aktualisierung erforderlich ist.

Beispielsweise:

import { cookies, headers } from 'next/headers'
const token = cookies().get('token')
 
function useToken() {
  const token = cookies().get('token')
  return token
}
 
export default function Page() {
  const name = cookies().get('name')
}
 
function getHeader() {
  return headers().get('x-foo')
}

Wird transformiert zu:

import { use } from 'react'
import { cookies, headers, type UnsafeUnwrappedCookies } from 'next/headers'
 
const token = (await cookies()).get('token')
 
function useToken() {
  const token = use(cookies()).get('token')
  return token
}
 
export default function Page() {
  const name = (await cookies()).get('name')
}
 
function getHeader() {
  return (headers() as UnsafeUnwrappedCookies).get('x-foo')
}

Wenn wir Eigenschaftszugriffe auf die params- oder searchParams-Eigenschaften in den Seiten-/Routeneinträgen (page.js, layout.js, route.js oder default.js) oder den generateMetadata- / generateViewport-APIs erkennen, wird versucht, den Aufrufungsort von einer synchronen zu einer asynchronen Funktion zu transformieren und den Eigenschaftszugriff abzuwarten. Wenn es nicht asynchron gemacht werden kann (z.B. bei einer Client-Komponente), wird React.use verwendet, um das Promise zu entpacken.

Beispielsweise:

// page.tsx
export default function Page({
  params,
  searchParams,
}: {
  params: { slug: string }
  searchParams: { [key: string]: string | string[] | undefined }
}) {
  const { value } = searchParams
  if (value === 'foo') {
    // ...
  }
}
 
export function generateMetadata({ params }: { params: { slug: string } }) {
  return {
    title: `My Page - ${slug}`,
  }
}

Wird transformiert zu:

// page.tsx
export default function Page(props: {
  params: { slug: string }
  searchParams: { [key: string]: string | string[] | undefined }
}) {
  const { value } = await props.searchParams
  if (value === 'foo') {
    // ...
  }
}
 
export function generateMetadata(props: { params: { slug: string } }) {
  const { slug } = await props.params
  return {
    title: `My Page - ${slug}`,
  }
}

Hinweis: Wenn dieser Codemod eine Stelle identifiziert, die möglicherweise manuelle Eingriffe erfordert, aber wir nicht in der Lage sind, die genaue Lösung zu bestimmen, wird er einen Kommentar oder eine Typumwandlung zum Code hinzufügen, um den Benutzer zu informieren, dass eine manuelle Aktualisierung erforderlich ist. Diese Kommentare beginnen mit @next/codemod, und Typumwandlungen sind mit UnsafeUnwrapped gekennzeichnet. Der Build wird fehlschlagen, bis diese Kommentare explizit entfernt werden. Weitere Informationen.

Ersetzen der geo- und ip-Eigenschaften von NextRequest mit @vercel/functions

next-request-geo-ip
Terminal
npx @next/codemod@latest next-request-geo-ip .

Dieser Codemod installiert @vercel/functions und transformiert die geo- und ip-Eigenschaften von NextRequest mit entsprechenden @vercel/functions-Funktionen.

Beispielsweise:

import type { NextRequest } from 'next/server'
 
export function GET(req: NextRequest) {
  const { geo, ip } = req
}

Wird transformiert zu:

import type { NextRequest } from 'next/server'
import { geolocation, ipAddress } from '@vercel/functions'
 
export function GET(req: NextRequest) {
  const geo = geolocation(req)
  const ip = ipAddress(req)
}

14.0

Migration der ImageResponse-Importe

next-og-import
Terminal
npx @next/codemod@latest next-og-import .

Dieser Codemod transformiert Importe von next/server zu next/og für die Verwendung der Dynamischen OG-Bildgenerierung.

Beispielsweise:

import { ImageResponse } from 'next/server'

Wird transformiert zu:

import { ImageResponse } from 'next/og'

Verwendung des viewport-Exports

metadata-to-viewport-export
Terminal
npx @next/codemod@latest metadata-to-viewport-export .

Dieser Codemod migriert bestimmte Viewport-Metadaten zum viewport-Export.

Beispielsweise:

export const metadata = {
  title: 'My App',
  themeColor: 'dark',
  viewport: {
    width: 1,
  },
}

Wird transformiert zu:

export const metadata = {
  title: 'My App',
}
 
export const viewport = {
  width: 1,
  themeColor: 'dark',
}

13.2

Verwendung der integrierten Schriftart

built-in-next-font
Terminal
npx @next/codemod@latest built-in-next-font .

Dieser Codemod deinstalliert das @next/font-Paket und transformiert @next/font-Importe in die integrierte next/font.

Beispielsweise:

import { Inter } from '@next/font/google'

Wird transformiert zu:

import { Inter } from 'next/font/google'

13.0

Umbenennen der Next Image-Importe

next-image-to-legacy-image
Terminal
npx @next/codemod@latest next-image-to-legacy-image .

Benennt next/image-Importe in bestehenden Next.js 10-, 11- oder 12-Anwendungen sicher zu next/legacy/image in Next.js 13 um. Benennt auch next/future/image zu next/image um.

Beispielsweise:

pages/index.js
import Image1 from 'next/image'
import Image2 from 'next/future/image'
 
export default function Home() {
  return (
    <div>
      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />
    </div>
  )
}

Wird transformiert zu:

pages/index.js
// 'next/image' wird zu 'next/legacy/image'
import Image1 from 'next/legacy/image'
// 'next/future/image' wird zu 'next/image'
import Image2 from 'next/image'
 
export default function Home() {
  return (
    <div>
      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />
    </div>
  )
}

Migration zur neuen Image-Komponente

next-image-experimental
Terminal
npx @next/codemod@latest next-image-experimental .

Migriert gefährlich von next/legacy/image zur neuen next/image, indem Inline-Stile hinzugefügt und nicht verwendete Eigenschaften entfernt werden.

  • Entfernt die layout-Eigenschaft und fügt style hinzu.
  • Entfernt die objectFit-Eigenschaft und fügt style hinzu.
  • Entfernt die objectPosition-Eigenschaft und fügt style hinzu.
  • Entfernt die lazyBoundary-Eigenschaft.
  • Entfernt die lazyRoot-Eigenschaft.
Terminal
npx @next/codemod@latest new-link .

Entfernen Sie <a>-Tags innerhalb von Link-Komponenten oder fügen Sie eine legacyBehavior-Eigenschaft zu Links hinzu, die nicht automatisch korrigiert werden können.

Beispielsweise:

<Link href="/about">
  <a>About</a>
</Link>
// wird umgewandelt in
<Link href="/about">
  About
</Link>
 
<Link href="/about">
  <a onClick={() => console.log('clicked')}>About</a>
</Link>
// wird umgewandelt in
<Link href="/about" onClick={() => console.log('clicked')}>
  About
</Link>

In Fällen, in denen keine automatische Korrektur möglich ist, wird die legacyBehavior-Eigenschaft hinzugefügt. Dies ermöglicht es Ihrer App, für diesen speziellen Link weiterhin das alte Verhalten zu verwenden.

const Component = () => <a>About</a>
 
<Link href="/about">
  <Component />
</Link>
// wird zu
<Link href="/about" legacyBehavior>
  <Component />
</Link>

11

Migration von CRA

cra-to-next
Terminal
npx @next/codemod cra-to-next

Migriert ein Create React App-Projekt zu Next.js; erstellt einen Pages Router und die notwendige Konfiguration, um das Verhalten zu übereinstimmen. Die serverseitige Rendering wird zunächst nur clientseitig genutzt, um die Kompatibilität aufgrund von window-Nutzung während des SSR zu verhindern und kann nahtlos aktiviert werden, um die schrittweise Einführung von Next.js-spezifischen Funktionen zu ermöglichen.

Bitte teilen Sie Ihr Feedback zu dieser Transformation in dieser Diskussion mit.

10

React-Imports hinzufügen

add-missing-react-import
Terminal
npx @next/codemod add-missing-react-import

Transformiert Dateien, die React nicht importieren, um den Import hinzuzufügen, damit die neue React JSX-Transformation funktioniert.

Beispielsweise:

my-component.js
export default class Home extends React.Component {
  render() {
    return <div>Hello World</div>
  }
}

Wird umgewandelt in:

my-component.js
import React from 'react'
export default class Home extends React.Component {
  render() {
    return <div>Hello World</div>
  }
}

9

Anonyme Komponenten in benannte Komponenten transformieren

name-default-component
Terminal
npx @next/codemod name-default-component

Versionen 9 und höher.

Transformiert anonyme Komponenten in benannte Komponenten, um sicherzustellen, dass sie mit Fast Refresh funktionieren.

Beispielsweise:

my-component.js
export default function () {
  return <div>Hello World</div>
}

Wird umgewandelt in:

my-component.js
export default function MyComponent() {
  return <div>Hello World</div>
}

Die Komponente erhält einen kamelgroßen Namen basierend auf dem Dateinamen und funktioniert auch mit Pfeilfunktionen.

8

AMP HOC in Seitenkonfiguration transformieren

withamp-to-config
Terminal
npx @next/codemod withamp-to-config

Transformiert das withAmp HOC in die Next.js 9 Seitenkonfiguration.

Beispielsweise:

// Vorher
import { withAmp } from 'next/amp'
 
function Home() {
  return <h1>My AMP Page</h1>
}
 
export default withAmp(Home)
// Nachher
export default function Home() {
  return <h1>My AMP Page</h1>
}
 
export const config = {
  amp: true,
}

6

Verwenden von withRouter

url-to-withrouter
Terminal
npx @next/codemod url-to-withrouter

Transformiert die veraltete, automatisch injizierte url-Eigenschaft auf Seiten der obersten Ebene zur Verwendung von withRouter und der Router-Eigenschaft, die es injiziert. Weitere Informationen hier: https://nextjs.org/docs/messages/url-deprecated

Beispielsweise:

Von
import React from 'react'
export default class extends React.Component {
  render() {
    const { pathname } = this.props.url
    return <div>Current pathname: {pathname}</div>
  }
}
Zu
import React from 'react'
import { withRouter } from 'next/router'
export default withRouter(
  class extends React.Component {
    render() {
      const { pathname } = this.props.router
      return <div>Current pathname: {pathname}</div>
    }
  }
)

Dies ist ein Fall. Alle Fälle, die transformiert (und getestet) werden, können im __testfixtures__-Verzeichnis gefunden werden.