Après 70 versions canaries, nous sommes heureux de présenter Next.js 9, avec :
- Support intégré de TypeScript sans configuration : Développez votre application avec plus de confiance grâce au support automatique de TypeScript et à la vérification intégrée des types.
- Routage dynamique basé sur le système de fichiers : Exprimez des besoins complexes de routage d'application via le système de fichiers sans avoir besoin d'un serveur personnalisé.
- Optimisation statique automatique : Créez des sites ultra-rapides exploitant par défaut le Server-Side Rendering et le Prerendering Statique sans compromettre les fonctionnalités.
- Routes API : Construisez rapidement des endpoints backend pour votre application, en profitant du hot-reloading et d'un pipeline de build unifié.
- Plus d'optimisations pour la production : Les applications sont plus réactives que jamais grâce au préchargement dans le viewport et d'autres optimisations.
- Améliorations de l'expérience développeur : Des améliorations discrètes et faciles à utiliser pour vous aider à développer dans les meilleures conditions.
Comme toujours, nous nous sommes efforcés de garantir que tous ces avantages soient rétrocompatibles. Pour la plupart des applications Next.js, il vous suffit d'exécuter :
npm i next@latest react@latest react-dom@latest
Il y a très peu de cas où votre codebase pourrait nécessiter des modifications. Consultez le guide de mise à niveau pour plus d'informations.
Depuis notre dernière version, nous sommes heureux d'avoir vu des entreprises comme IGN, Bang & Olufsen, Intercom, Buffer, et Ferrari lancer des projets avec Next.js. Découvrez-en plus dans notre showcase !
Support intégré de TypeScript sans configuration
Il y a un an, Next.js 6 introduisait un support basique de TypeScript via un plugin appelé @zeit/next-typescript
. Les utilisateurs devaient également personnaliser leur .babelrc
et l'activer dans next.config.js
.
Une fois configuré, le plugin permettait à Next.js de compiler les fichiers .ts
et .tsx
. Cependant, il n'intégrait pas la vérification des types, et les types n'étaient pas fournis par le cœur de Next.js. Cela signifiait qu'un package communautaire devait être maintenu séparément dans DefinitelyTyped, pouvant être désynchronisé avec les versions.
En discutant avec de nombreux utilisateurs, existants et nouveaux, il est devenu clair que la plupart étaient très intéressés par l'utilisation de TypeScript. Ils voulaient une solution plus fiable et standard pour intégrer facilement TypeScript dans leur codebase existante ou nouvelle.
Pour cette raison, nous avons décidé d'intégrer le support de TypeScript dans le cœur de Next.js, améliorant ainsi l'expérience développeur et rendant le processus plus rapide.
Configuration automatisée
Commencer avec TypeScript dans Next.js est simple : renommez n'importe quel fichier, page ou composant, de .js
à .tsx
. Ensuite, exécutez next dev
!
Cela permettra à Next.js de détecter que TypeScript est utilisé dans votre projet. Le CLI de Next.js vous guidera pour installer les types nécessaires pour React et Node.js.
Next.js créera également un tsconfig.json
par défaut avec des paramètres raisonnables s'il n'est pas déjà présent. Ce fichier permet une vérification intégrée des types dans des éditeurs comme Visual Studio Code.
Configuration automatisée de TypeScript dans Next.js 9
Vérification intégrée des types
Next.js gère la vérification des types pour vous, à la fois en développement et lors de la construction pour la production.
En développement, Next.js vous montrera les erreurs de type après avoir sauvegardé un fichier. La vérification des types se fait en arrière-plan, vous permettant d'interagir avec votre application mise à jour dans le navigateur instantanément. Les erreurs de type seront propagées vers le navigateur dès qu'elles seront disponibles.
Vérification des types en développement avec Next.js 9
Next.js fera également échouer automatiquement la construction pour la production (c'est-à-dire next build
) si des erreurs de type sont présentes. Cela aide à éviter d'envoyer du code cassé en production.
Vérification des types en production avec Next.js 9
Le cœur de Next.js écrit en TypeScript
Au cours des derniers mois, nous avons migré la majeure partie de la codebase vers TypeScript. Cela a non seulement renforcé la qualité de notre code, mais nous permet également de fournir des types pour tous les modules principaux.
Par exemple, lorsque vous importez next/link
, les éditeurs supportant TypeScript afficheront les propriétés autorisées et les valeurs qu'elles acceptent.
Types du cœur de Next.js
Segments de route dynamique
Le routage dynamique (également connu sous le nom de slugs d'URL ou URLs propres/élégantes) était l'une des premières demandes de fonctionnalité sur GitHub après la sortie de Next.js il y a 2,5 ans !
Le problème a été "résolu" dans Next.js 2.0 en introduisant l'API de serveur personnalisé pour utiliser Next.js de manière programmatique. Cela permettait d'utiliser Next.js comme un moteur de rendu, permettant des abstractions et le mappage des URLs entrantes pour rendre certaines pages.
Nous avons discuté avec les utilisateurs et examiné de nombreuses de leurs applications, constatant que beaucoup d'entre elles avaient un serveur personnalisé. Un schéma est apparu : la raison principale du serveur personnalisé était le routage dynamique.
Cependant, un serveur personnalisé a ses propres pièges : le routage est géré au niveau du serveur au lieu du proxy, il est déployé et mis à l'échelle comme un monolithe, et il est sujet à des problèmes de performance.
Puisqu'un serveur personnalisé nécessite que toute l'application soit disponible dans une seule instance, il est généralement difficile de le déployer dans un environnement Serverless qui résout ces problèmes. Les requêtes Serverless sont routées au niveau du proxy et sont mises à l'échelle/exécutées indépendamment pour éviter les goulots d'étranglement de performance.
De plus, nous pensons que nous pouvons offrir une meilleure expérience développeur ! Une grande partie de la magie de Next.js commence lorsque vous créez un fichier nommé pages/blog.js
et que vous avez soudainement une page accessible à /blog
.
Pourquoi un utilisateur devrait-il avoir besoin de créer son propre serveur et d'apprendre l'API programmatique de Next.js pour supporter une route comme /blog/my-first-post
(/blog/:id
) ?
Sur la base de ces retours et de cette vision, nous avons commencé à explorer des solutions de mappage de routes, guidés par ce que les utilisateurs connaissaient déjà : le répertoire pages/
.
Création d'une page avec routage dynamique
Next.js supporte la création de routes avec des paramètres nommés basiques, un schéma popularisé par path-to-regexp
(la bibliothèque qui alimente Express).
Créer une page qui correspond à la route /post/:pid
peut maintenant être réalisé en créant un fichier dans votre répertoire pages
nommé : pages/post/[pid].js
!
Next.js fera automatiquement correspondre les requêtes comme /post/1
, /post/hello-nextjs
, etc. et rendra la page définie dans pages/post/[pid].js
. Le segment d'URL correspondant sera passé comme paramètre de requête à votre page avec le nom spécifié entre les [crochets]
.
Par exemple : étant donné la page suivante et la requête /post/hello-nextjs
, l'objet query
sera { pid: 'hello-nextjs' }
:
static async getInitialProps({ query }) {
// pid = 'hello-nextjs'
const { pid } = query
const postContent = await fetch(
`https://api.example.com/post/${encodeURIComponent(pid)}`
).then(r => r.text())
return { postContent }
}
Plusieurs segments d'URL dynamiques sont également supportés !
La syntaxe [param]
est supportée pour les noms de répertoires et de fichiers, ce qui signifie que les exemples suivants fonctionnent :
./pages/blog/[blogId]/comments/[commentId].js
./pages/posts/[pid]/index.js
Vous pouvez en savoir plus sur cette fonctionnalité dans la documentation de Next.js ou dans la section Next.js Learn.
Optimisation statique automatique
Next.js a ajouté le support de la génération de sites statiques dans la version 3, sortie il y a environ deux ans. À l'époque, c'était la fonctionnalité la plus demandée pour Next.js.
Et pour une bonne raison : il est indéniable que les sites statiques sont rapides ! Ils ne nécessitent aucun calcul côté serveur et peuvent être instantanément diffusés à l'utilisateur final depuis des emplacements CDN.
Cependant, le choix entre une application rendue côté serveur ou générée statiquement était binaire, vous choisissiez soit le rendu côté serveur, soit la génération statique. Il n'y avait pas de juste milieu.
En réalité, les applications peuvent avoir des besoins différents. Ces besoins nécessitent des stratégies de rendu et des compromis différents.
Par exemple, une page d'accueil et des pages marketing contiennent généralement du contenu statique et sont d'excellents candidats pour l'optimisation statique.
D'un autre côté, un tableau de bord de produit peut bénéficier d'être rendu côté serveur où les données sont fréquemment mises à jour.
Nous avons commencé à explorer comment nous pourrions donner aux utilisateurs le meilleur des deux mondes et être rapides par défaut. Comment pourrions-nous donner aux utilisateurs des pages marketing statiques et des pages dynamiques rendues côté serveur ?
À partir de Next.js 9, les utilisateurs n'ont plus à choisir entre un rendu entièrement côté serveur ou une exportation statique de leur application. Vous obtenez le meilleur des deux mondes sur une base par page.
Exportation statique partielle automatique
Une heuristique a été introduite pour déterminer automatiquement si une page peut être prérendue en HTML statique.
Cette détermination est faite en fonction de si la page a ou non des besoins en données bloquantes via l'utilisation de getInitialProps
.
Cette heuristique permet à Next.js d'émettre des applications hybrides qui contiennent à la fois des pages rendues côté serveur et des pages générées statiquement.
Le serveur intégré de Next.js (next start
) et l'API programmatique (app.getRequestHandler()
) supportent tous deux cette sortie de build de manière transparente. Aucune configuration ou gestion spéciale n'est requise.
Les pages générées statiquement restent réactives : Next.js hydratera votre application côté client pour lui donner une interactivité complète.
De plus, Next.js mettra à jour votre application après l'hydratation si la page dépend des paramètres de requête dans l'URL.
Next.js vous informera visuellement si une page sera générée statiquement pendant le développement. Cet artefact visuel peut être masqué en cliquant dessus.
Indicateur d'optimisation statique de Next.js
Les pages générées statiquement seront également affichées dans la sortie de build de Next.js :
Indicateur de type de sortie de build de Next.js
Routes API
Dans de nombreux cas, lorsque vous construisez des applications React, vous finissez par avoir besoin d'une sorte de backend. Soit pour récupérer des données depuis une base de données, soit pour traiter des données fournies par vos utilisateurs (par exemple, un formulaire de contact).
Nous avons constaté que de nombreux utilisateurs qui avaient besoin d'un backend construisaient leur API en utilisant un serveur personnalisé. Ce faisant, ils rencontraient plusieurs problèmes. Par exemple, Next.js ne compile pas le code du serveur personnalisé, ce qui signifie que vous ne pouviez pas utiliser import
/ export
ou TypeScript.
Pour cette raison, de nombreux utilisateurs finissaient par implémenter leur propre pipeline de compilation personnalisé en plus du serveur personnalisé. Bien que cela résolve leur objectif, cela est sujet à de nombreux pièges : par exemple, lorsqu'il est mal configuré, l'élagage d'arbre serait désactivé pour toute leur application.
Cela a soulevé la question : et si nous apportions l'expérience développeur que Next.js offre à la construction de backends API ?
Aujourd'hui, nous sommes ravis de présenter les routes API, la meilleure expérience développeur de Next.js pour construire votre backend.
Pour commencer à utiliser les routes API, vous créez un répertoire appelé api/
à l'intérieur du répertoire pages/
.
Tout fichier dans ce répertoire sera automatiquement mappé à /api/<votre route>
, de la même manière que les autres fichiers de page sont mappés à des routes.
Par exemple, pages/api/contact.js
sera mappé à /api/contact
.
Note : Les routes API supportent également les routes dynamiques !
Tous les fichiers à l'intérieur du répertoire pages/api/
exportent une fonction de gestionnaire de requête au lieu d'un composant React :
export default function handle(req, res) {
res.end('Hello World');
}
req
fait référence à NextApiRequest qui étend http.IncomingMessageres
fait référence à NextApiResponse qui étend http.ServerResponse
Généralement, les endpoints API prennent certaines données entrantes, par exemple la chaîne de requête, le corps de la requête ou les cookies, et répondent avec d'autres données.
En enquêtant sur l'ajout du support des routes API à Next.js, nous avons remarqué que dans de nombreux cas, les utilisateurs n'utilisaient pas directement les objets de requête et de réponse de Node.js. Au lieu de cela, ils utilisaient une abstraction fournie par des bibliothèques serveur comme Express.
La raison en est que dans de nombreux cas, les données entrantes sont une forme de texte qui doit d'abord être analysée pour être utile. Ces bibliothèques serveur spécifiques aident donc à supprimer la charge de l'analyse manuelle des données, le plus souvent via des middlewares. Les plus couramment utilisées fournissent l'analyse de la chaîne de requête, du corps et des cookies, mais elles nécessitent tout de même une certaine configuration pour démarrer.
Les routes API dans Next.js fourniront ces middlewares par défaut afin que vous puissiez être productif immédiatement lors de la création d'endpoints API :
export default function handle(req, res) {
console.log(req.body); // Le corps de la requête
console.log(req.query); // La chaîne de requête de l'URL
console.log(req.cookies); // Les cookies transmis
res.end('Hello World');
}
En plus d'utiliser les données entrantes, votre endpoint API retourne généralement également des données. Communément, cette réponse sera en JSON. Next.js fournit res.json()
par défaut pour faciliter l'envoi de données :
export default function handle(req, res) {
res.json({ title: 'Hello World' });
}
Lorsque vous apportez des modifications aux endpoints API en développement, le code est automatiquement rechargé, il n'est donc pas nécessaire de redémarrer le serveur.
Optimisations pour la production
Préchargement des <Link>
dans le viewport
Next.js 9 préchargera automatiquement les composants <Link>
lorsqu'ils apparaîtront dans le viewport.
Cette fonctionnalité améliore la réactivité de votre application en rendant les navigations vers de nouvelles pages plus rapides.
Next.js utilise un Intersection Observer pour précharger les assets nécessaires en arrière-plan.
Ces requêtes ont une priorité basse et cèdent le pas aux requêtes fetch()
ou XHR. Next.js évitera de précharger automatiquement si l'utilisateur a activé l'économiseur de données.
Vous pouvez désactiver cette fonctionnalité pour les pages rarement visitées en définissant la propriété prefetch
à false
:
<Link href="/terms" prefetch={false}>
<a>Conditions d'utilisation</a>
</Link>
Optimisation AMP par défaut
Next.js 9 rend désormais les pages AMP optimisées par défaut pour les pages AMP-first et hybrides.
Bien que les pages AMP soient optionnelles, Next.js optimise automatiquement leur sortie. Ces optimisations peuvent entraîner une vitesse de rendu jusqu'à 50 % plus rapide !
Ce changement a été rendu possible grâce au travail remarquable de Sebastian Benz sur l'AMP Optimizer.
Élimination du code mort pour les branches typeof window
Next.js 9 remplace typeof window
par sa valeur appropriée (undefined
ou object
) lors des builds côté serveur et client. Ce changement permet à Next.js de supprimer automatiquement le code mort de votre application en production.
Les utilisateurs devraient voir la taille de leurs bundles côté client diminuer s'ils ont du code réservé au serveur dans getInitialProps
ou d'autres parties de leur application.
Améliorations de l'expérience développeur
Indicateur de compilation
Dans les versions antérieures à 9, la seule façon de savoir qu'un remplacement de code à chaud allait avoir lieu (et que la chaîne d'outils de compilation de Next.js travaillait) était de regarder la console du développeur.
Cependant, on regarde souvent le rendu résultant, ce qui rend difficile de savoir si Next.js est encore en train de compiler ou non. Par exemple, vous pourriez faire des modifications subtiles de styles sur la page et ne pas savoir immédiatement si elles ont été mises à jour.
Pour cette raison, nous avons créé un RFC / "good first issue" pour discuter des solutions potentielles pour indiquer que du travail est en cours.
Nous avons reçu des retours de nombreux designers et ingénieurs sur le RFC, par exemple sur leurs préférences et des pistes de conception pour l'indicateur.
Rafael Almeida a saisi cette opportunité pour collaborer avec notre équipe et implémenter un tout nouvel indicateur désormais disponible par défaut dans Next.js 9.
Dès que Next.js effectue un travail de compilation, vous verrez un petit triangle apparaître dans le coin inférieur droit de la page !
Indicateur de compilation Next.js
Sortie console
Traditionnellement, lors de modifications en développement, Next.js affichait un indicateur de compilation avec des barres de chargement qui se remplissaient et effaçait continuellement l'écran à chaque modification.
Ce comportement posait quelques problèmes. Notamment, il effaçait la sortie console de votre code applicatif, par exemple lorsque vous ajoutiez console.log
à vos composants. Mais aussi lors de l'utilisation d'outils externes qui agrègent les logs comme la Vercel CLI ou docker-compose
.
À partir de Next.js 9, la sortie des logs saute moins et n'efface plus l'écran. Cela permet une meilleure expérience globale car votre terminal contiendra plus d'informations pertinentes et scintillera moins, tandis que Next.js s'intégrera mieux avec les outils que vous utilisez peut-être déjà.
Sortie console de développement Next.js
Un grand merci à Justin Chase pour sa collaboration sur l'effacement de la sortie.
Statistiques de build
Lors de la construction de votre application pour la production avec next build
, vous obtiendrez désormais une vue détaillée de toutes les pages construites.
Chaque page reçoit automatiquement quelques statistiques.
La plus importante est la taille du bundle. À mesure que votre application grandit, vos bundles JavaScript grossissent également. Cette indication au moment du build vous aidera à suivre la croissance de vos bundles en production. À l'avenir, vous pourrez également définir des budgets de performance pour les pages qui feront échouer le build de production.
Taille des pages construites avec Next.js
Outre les tailles de bundles, nous montrons également combien de composants du projet et de node_modules
sont utilisés dans chaque page. Cela donne une indication de la complexité de la page.
Nombre de packages par page Next.js
Chaque page indique également si elle est optimisée statiquement ou rendue côté serveur, car chaque page peut se comporter différemment.
Type de page construite avec Next.js
Objet de configuration par page
Chaque page peut désormais exporter un objet de configuration. Initialement, cette configuration permet d'opter pour AMP, mais à l'avenir, vous pourrez configurer davantage d'options spécifiques à la page.
export const config = { amp: true };
export default function AboutPage(props) {
return <h3>Ma page AMP À propos !</h3>;
}
Pour opter pour un rendu AMP hybride, vous pouvez utiliser la valeur 'hybrid'
:
import { useAmp } from 'next/amp';
export const config = { amp: 'hybrid' };
export default function AboutPage(props) {
const isAmp = useAmp();
return <h3>Ma page À propos !{isAmp ? <> Propulsé par AMP !</> : ''}</h3>;
}
Le composant d'ordre supérieur withAmp
a été supprimé au profit de cette nouvelle configuration.
Nous avons fourni un codemod qui convertit automatiquement l'utilisation de withAmp
vers le nouvel objet de configuration. Vous pouvez en savoir plus dans le guide de mise à niveau.
Améliorations du codebase
Nous avons récemment apporté des modifications à nos outils pour offrir une meilleure expérience lors de la contribution au codebase et garantir la stabilité à mesure que le codebase grandit.
Comme vous l'avez lu dans la section TypeScript, le cœur de Next.js est maintenant écrit en TypeScript et les types sont générés automatiquement pour les applications Next.js. Outre son utilité pour les applications construites avec Next.js, cela est également utile lors du travail sur le codebase principal, car vous obtenez automatiquement des erreurs de type et de l'autocomplétion.
Next.js disposait déjà d'une importante suite de tests d'intégration composée de 50+ applications Next.js avec des tests exécutés contre elles. Ces tests garantissent que lors de la sortie d'une nouvelle version, la mise à niveau se passe bien car les fonctionnalités disponibles auparavant ont été testées contre la même suite de tests.
La plupart de nos tests sont des tests d'intégration car dans de nombreux cas, ils reproduisent des développeurs "réels" utilisant Next.js en développement. Par exemple, nous avons des tests qui reproduisent des modifications apportées à une application Next.js pour vérifier si le remplacement de module à chaud fonctionne.
Nos tests d'intégration sont principalement basés sur Selenium WebDriver, que nous avons combiné avec chromedriver pour tester dans Chrome sans interface. Cependant, avec le temps, certains problèmes sont apparus dans d'autres navigateurs, notamment les anciens navigateurs comme Internet Explorer 11.
Comme nous utilisions Selenium, nous pouvions exécuter nos tests automatiquement sur plusieurs navigateurs.
Actuellement, nous exécutons notre suite de tests sur Chrome, Firefox, Safari et Internet Explorer 11.
Collaboration avec Google Chrome
L'équipe Google Chrome a travaillé à l'amélioration de Next.js en contribuant des RFC et des pull-requests.
L'objectif de cette collaboration est d'apporter des améliorations de performance à grande échelle, axées sur les tailles de bundles, le temps de démarrage et d'hydratation.
Par exemple, ces changements amélioreront l'expérience des petits sites web, mais aussi celle d'applications massives comme Hulu, Twitch et Deliveroo.
Module / Nomodule
Le premier domaine d'attention est l'envoi de JavaScript moderne aux navigateurs qui le supportent.
Par exemple, actuellement Next.js doit fournir des polyfills pour la syntaxe async
/await
car le code pourrait être exécuté dans des navigateurs qui ne supportent pas async
/await
, ce qui le ferait échouer.
RFC de collaboration Module/Nomodule Next.js
Pour éviter de casser les anciens navigateurs tout en envoyant du JavaScript moderne aux navigateurs qui le supportent, Next.js utilisera le modèle module/nomodule. Ce modèle fournit un mécanisme fiable pour servir du JavaScript moderne aux navigateurs modernes tout en permettant aux anciens navigateurs de revenir à de l'ES5 polyfillé.
Le RFC pour module/nomodule dans Next.js peut être trouvé ici.
Amélioration du découpage des bundles
La stratégie actuelle de découpage des bundles dans Next.js est basée sur une heuristique ratio pour inclure des modules dans un seul chunk "commons". Comme il y a très peu de granularité puisqu'il n'y a qu'un seul bundle, le code est soit téléchargé inutilement (car le chunk commons pourrait inclure du code qui n'est pas réellement nécessaire pour une route particulière), soit le code est dupliqué dans plusieurs bundles de page.
RFC de collaboration sur le découpage Next.js
Le RFC pour l'amélioration du découpage des bundles peut être trouvé ici.
Autres améliorations
L'équipe Chrome travaille également sur de nombreuses autres optimisations et changements qui amélioreront Next.js. Les RFC pour ceux-ci seront partagés bientôt.
Ces RFC et pull-requests sont étiquetés "Collaboration" pour qu'ils puissent être facilement trouvés dans le suivi des problèmes de Next.js.
Communauté
Nous sommes ravis de voir la croissance continue de la communauté Next.js.
Cette version a eu plus de 65 auteurs de pull-requests contribuant des améliorations ou des exemples.
En parlant d'exemples, nous fournissons désormais plus de 200 exemples sur la façon d'intégrer Next.js avec différentes bibliothèques et technologies ! Y compris la plupart des bibliothèques css-in-js et de récupération de données.
- Nous avons eu plus de 720 contributeurs ayant validé au moins 1 commit.
- Sur GitHub, le projet a été mis en favori plus de 38 600 fois.
- Plus de 3 400 pull requests ont été soumises depuis la première version, soit plus de 800 depuis la dernière version majeure !
La communauté Next.js a doublé depuis la dernière version majeure avec plus de 8 600 membres. Rejoignez-nous !
Nous sommes reconnaissants envers notre communauté et tous les retours et contributions externes qui ont aidé à façonner cette version.