Upgrade auf Next.js 16: Was laut scheitert und was leise kippt
Die meisten Breaking Changes in 16 stoppen den Build - das macht sie ungefährlich. Planen müssen Sie für die wenigen, die das Verhalten ändern, ohne etwas zu sagen.
Next.js 16 bringt eine lange Liste von Breaking Changes, und die meisten davon sind die gute Sorte: Sie stoppen den Build. Sie führen ihn aus, er schlägt fehl, Sie beheben es, weiter geht es.
Sorgfältig lesen sollten Sie die wenigen, die das Verhalten ändern, ohne irgendetwas fehlschlagen zu lassen. Die gehen in Produktion.
Dieser Text entsteht aus einer Codebasis mit 16.3 - der Website, auf der Sie ihn lesen.
Die eine architektonische Entscheidung: aus middleware wurde proxy
middleware.ts ist veraltet und heißt jetzt proxy.ts, die exportierte
Funktion middleware entsprechend proxy. Die Umbenennung übernimmt der
Codemod.
Was der Codemod nicht übernehmen kann, ist die Entscheidung darunter, und die ist real:
Die
edge-Runtime wird inproxynicht unterstützt. Die Proxy-Runtime istnodejsund lässt sich nicht konfigurieren.
Wenn Ihre Middleware auf der Edge lief - und standardmäßig tat sie das -, verschiebt das Umbenennen der Datei diese Arbeit von hundert Edge-Standorten auf Ihren Node-Server. Für ein Rewrite oder einen Locale-Redirect, der bei jedem Request läuft, ist das keine Umbenennung, sondern eine Verschiebung der Latenz.
Der dokumentierte Weg, wenn Sie die Edge-Runtime brauchen: vorerst bei
middleware bleiben. Das Upgrade hat also eine Weggabelung:
- Leichte Routing-Arbeit - Rewrites, Redirects, ein Cookie-Read - nach
proxyverschieben und die Node-Runtime akzeptieren. - Latenzkritisches auf der Edge - bei
middlewarebleiben, bis die Folgeanleitung kommt, im Wissen, auf einer veralteten Konvention zu sitzen.
So oder so ist das der Moment zu prüfen, ob der Matcher je richtig war. Middleware läuft bei jedem Request, auch bei denen, die Sie vergessen haben - und jeder dieser Requests geht jetzt zum Origin.
Mit umbenannt werden die Konfigurationsflags: aus
skipMiddlewareUrlNormalize wird skipProxyUrlNormalize. Das erledigt der
Codemod.
Was laut scheitert, sodass Sie es nicht ausliefern können
Eine Webpack-Konfiguration mit next build. Turbopack ist jetzt auch für
next build der Standard, nicht nur für next dev, und ein Projekt mit
eigener Webpack-Konfiguration lässt den Build bewusst scheitern, statt sie
still zu ignorieren. Drei Auswege: mit --turbopack bauen und die
Konfiguration ignorieren, sie auf Turbopack-Optionen portieren, oder mit
--webpack aussteigen. Gut zu wissen: Möglicherweise fügt ein Plugin eine
Webpack-Option hinzu, die Sie nie geschrieben haben - das ist die verwirrende
Variante dieses Fehlers.
Parallele Routen ohne default.js. Jeder Slot braucht jetzt eine
explizite default.js, sonst scheitert der Build. Eine Datei, die
notFound() aufruft oder null zurückgibt, stellt das vorherige Verhalten
her.
Node 18. Das Minimum ist jetzt Node 20.9, bei TypeScript 5.1. Die Browser-Ziele liegen bei Chrome, Edge und Firefox 111+ sowie Safari 16.4+.
next lint, AMP und Runtime-Config. Alles entfernt.
serverRuntimeConfig und publicRuntimeConfig gibt es nicht mehr - nutzen
Sie Umgebungsvariablen. next/legacy/image ist veraltet, ebenso
images.domains, das durch remotePatterns ersetzt wurde.
Was leise kippt - und wofür Sie planen müssen
Bild-Caching ging von 60 Sekunden auf 4 Stunden.
images.minimumCacheTTL liegt jetzt bei 14400. Nichts wirft einen Fehler.
Wenn Sie sich auf den alten Standard verlassen haben, um tagsüber wechselnde
Bilder zu aktualisieren, tun sie das nicht mehr - und das Symptom ist ein
veraltetes Bild, das niemand reproduzieren kann, weil der Browser-Cache dem
Optimierer widerspricht. Setzen Sie es explizit zurück, wenn Sie es brauchen:
// next.config.ts
images: { minimumCacheTTL: 60 },next build führt kein Lint mehr aus. Wenn Ihre CI darauf zählte, dass
der Build Lint-Fehler findet, tut sie das nicht mehr - still.
@next/eslint-plugin-next nutzt außerdem jetzt standardmäßig die Flat
Config. Führen Sie ESLint oder Biome als eigenen Schritt aus, und prüfen Sie,
dass dieser Schritt existiert, bevor Sie annehmen, er sei grün.
Die Image-srcset-Standards haben sich verschoben. 16 wurde aus dem
Standard-imageSizes-Array entfernt, der qualities-Standard hat sich
geändert. Beides wirft keinen Fehler und ändert, was erzeugt, zwischen-
gespeichert und ausgeliefert wird.
Lokale Bilder mit Query-String brauchen jetzt Konfiguration.
/photo?v=1 verlangt einen images.localPatterns-Eintrag mit passendem
search. Dieser Fall wirft einen Fehler - aber nur auf den Routen, die das
Muster nutzen, und das sind womöglich nicht die aus Ihrem Smoke-Test.
Die Reihenfolge, die funktioniert
- Lesen Sie die Anleitung vor dem Codemod. Sie liegt ab 16.2 in
node_modules/next/dist/docs/, passend zur tatsächlich installierten Version statt zu dem, woran sich das Internet erinnert. - Führen Sie den Upgrade-Codemod aus, danach separat den Codemod für die
asynchronen Request-APIs, falls Sie noch synchrone
params,searchParams,cookies(),headers()oderdraftMode()aus der 15er-Kompatibilitätsphase haben. Der Upgrade-Codemod führt nicht jede Migration aus. - Entscheiden Sie die Proxy-Frage bewusst, denn nichts wird Sie danach fragen.
- Vergleichen Sie die Build-Ausgabe mit der alten. Welche Routen
○und welcheƒsind, sollte sich nicht geändert haben - und wenn doch, lohnt sich das Verständnis vor dem Deployment. - Prüfen Sie die leise Liste oben gegen Ihre eigene Konfiguration.
Wenn Sie mehrere Versionen zurückliegen
Der Schritt von 15 auf 16 ist überschaubar. Von 13 oder 14 aus anzukommen, mit einem Pages Router noch im Baum, ist ein anderes Projekt - und der Fehler besteht darin, es als ein Upgrade zu behandeln. Migration ohne Feature-Freeze beschreibt die Reihenfolge, die die Anwendung währenddessen auslieferbar hält, und Migration und Rettung ist genau diese Arbeit, von uns erledigt.
