Nous sommes ravis de vous présenter aujourd'hui Next.js 9.2, qui inclut :
- Support natif des feuilles de style CSS globales : Les applications peuvent maintenant importer directement des fichiers
.css
comme feuilles de style globales. - Support natif des modules CSS pour les styles au niveau composant : En utilisant la convention
.module.css
, vous pouvez importer et utiliser du CSS localement scoped n'importe où dans votre application. - Stratégie améliorée de découpage de code : L'équipe Google Chrome a fortement optimisé la stratégie de découpage de code de Next.js, résultant en des bundles côté client significativement plus petits. De plus, ils ont maximisé l'utilisation de HTTP/2 pour améliorer la vitesse de chargement des pages sans nuire aux performances HTTP/1.1.
- Routes dynamiques attrape-tout : Les routes dynamiques de Next.js supportent maintenant les routes attrape-tout, permettant de nouveaux cas d'usage, par exemple des sites alimentés par un CMS.
Tous ces avantages sont non-breaking et entièrement rétrocompatibles. Pour mettre à jour, il vous suffit d'exécuter :
npm i next@latest react@latest react-dom@latest
Support natif des feuilles de style CSS globales
Next.js 5 avait introduit le support de l'import CSS via un plugin custom appelé next-css
qui étendait le comportement de Next.js.
Au fil du temps, nous avons reçu des retours constants d'entreprises et d'utilisateurs de Next.js, mentionnant qu'ils finissaient souvent par ajouter next-css
à leur application.
De plus, next-css
avait quelques contraintes manquantes lors de l'import de CSS. Par exemple, vous pouviez importer un fichier CSS dans chaque fichier du projet, mais ce fichier CSS importé serait global pour toute l'application.
Afin d'améliorer l'expérience développeur et de résoudre ces incohérences, nous avons commencé à travailler sur l'intégration du support des imports CSS directement dans Next.js.
Nous sommes heureux d'annoncer que Next.js dispose maintenant d'un support natif pour importer des feuilles de style dans votre application.
Pour commencer à utiliser les imports CSS dans votre application, importez le fichier CSS dans pages/_app.js
.
Par exemple, considérez la feuille de style suivante nommée styles.css
à la racine de votre projet :
body {
padding: 20px 20px 60px;
margin: 0;
}
Créez un fichier pages/_app.js
s'il n'est pas déjà présent.
Puis, importez le fichier styles.css
:
import '../styles.css';
// Cet export par défaut est requis dans un nouveau fichier `pages/_app.js`.
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
Comme les feuilles de style sont globales par nature, elles doivent être importées dans le composant <App>
personnalisé. Ceci est nécessaire pour éviter les conflits de noms de classe et d'ordre pour les styles globaux.
En développement, cette façon d'exprimer les feuilles de style permet à vos styles d'être automatiquement mis à jour sur la page pendant que vous les éditez.
En production, tous les fichiers CSS seront automatiquement concaténés en un seul fichier .css
minifié. Ce fichier CSS sera chargé via une balise <link>
et automatiquement injecté dans le markup HTML généré par défaut par Next.js.
Cette nouvelle fonctionnalité est entièrement rétrocompatible. Si vous utilisez @zeit/next-css
ou d'autres plugins liés au CSS, la fonctionnalité est désactivée pour éviter les conflits.
Si vous utilisez actuellement @zeit/next-css
, nous vous recommandons de supprimer le plugin de votre next.config.js
et package.json
, passant ainsi au support CSS natif lors de la mise à jour.
Support natif des modules CSS pour les styles au niveau composant
Next.js supporte maintenant les modules CSS en utilisant la convention de nommage [name].module.css
.
Contrairement au support précédemment disponible dans Next.js 5 avec next-css
, le CSS global et les modules CSS peuvent maintenant coexister — next-css
nécessitait que tous les fichiers .css
de votre application soient traités comme globaux ou locaux, mais pas les deux.
Les modules CSS limitent la portée du CSS en créant automatiquement des noms de classe uniques. Cela vous permet d'utiliser le même nom de classe CSS dans différents fichiers sans craindre de collisions.
Ce comportement fait des modules CSS le moyen idéal pour inclure du CSS au niveau composant. Les fichiers de modules CSS peuvent être importés n'importe où dans votre application.
Par exemple, considérez un composant réutilisable Button
dans le dossier components/
:
D'abord, créez components/Button.module.css
avec le contenu suivant :
/*
Vous n'avez pas à vous soucier que .error {} entre en conflit avec d'autres fichiers
`.css` ou `.module.css` !
*/
.error {
color: white;
background-color: red;
}
Puis, créez components/Button.js
, en important et utilisant le fichier CSS ci-dessus :
import styles from './Button.module.css';
export function Button() {
return (
<button
type="button"
// Notez comment la classe "error" est accessible comme une propriété de l'objet
// `styles` importé.
className={styles.error}
>
Destroy
</button>
);
}
Les modules CSS sont une fonctionnalité optionnelle et ne sont activés que pour les fichiers avec l'extension .module.css
. Les feuilles de style <link>
classiques et les fichiers CSS globaux sont toujours supportés.
En production, tous les fichiers de modules CSS sont automatiquement concaténés en plusieurs fichiers .css
minifiés et découpés. Ces fichiers .css
représentent les chemins d'exécution critiques de votre application, garantissant que la quantité minimale de CSS est chargée par page pour que votre application s'affiche.
Comme ci-dessus, cette nouvelle fonctionnalité est entièrement rétrocompatible. Si vous utilisez @zeit/next-css
ou d'autres plugins liés au CSS, la fonctionnalité est désactivée pour éviter les conflits.
Si vous utilisez actuellement @zeit/next-css
, nous vous recommandons de supprimer le plugin de votre next.config.js
et package.json
, passant ainsi au support CSS natif.
Stratégie améliorée de découpage de code
Les versions de Next.js antérieures à 9.2 avaient un ensemble fixe de bundles JavaScript requis pour charger et rendre une page interactive :
- Le fichier JavaScript de la page
- Un fichier avec le JavaScript commun
- Le bundle runtime client-side de Next.js
- Le bundle runtime client-side de Webpack
- Les imports dynamiques (ajoutés via
next/dynamic
, quand utilisés)
Pour rendre la page interactive, tous ces bundles doivent être chargés car ils dépendent les uns des autres pour démarrer React dans le navigateur.
Comme tous ces bundles sont nécessaires pour que l'application devienne interactive, il est important qu'ils soient aussi optimisés que possible. En pratique, cela signifie ne pas télécharger excessivement du code provenant d'autres parties de l'application.
Pour cette raison, Next.js utilisait un bundle commons
qui contenait le JavaScript commun entre les pages. Le calcul de l'ancienne stratégie de découpage pour générer commons
était une heuristique basée sur un ratio d'utilisation. Si un module était utilisé dans plus de 50% de toutes les pages, il était marqué comme module commun. Sinon, il était inclus dans le fichier JavaScript de la page.
Cependant, les applications peuvent être composées de nombreux types de pages différents. Par exemple, des pages marketing, un blog et un tableau de bord. S'il y avait un grand nombre de pages marketing comparé aux autres types de pages, le calcul des commons résultait en des optimisations fortement concentrées sur les pages marketing.
Notre objectif est d'optimiser pour tous les types de pages, dans une seule application.
Alex Castle a proposé une nouvelle méthode de chunking (création de fichiers JavaScript séparés) qui permet un chunking optimisé des commons avec plusieurs fichiers, y compris quand de nombreux types de pages sont impliqués.
Aujourd'hui, nous sommes heureux d'annoncer que ce nouveau comportement de chunking est activé par défaut dans Next.js 9.2. Nous tenons à exprimer notre profonde gratitude à l'équipe Google Chrome et à Alex Castle pour avoir contribué à ce changement. Ce changement reflète l'effort cumulé de semaines de recherche, tests en laboratoire, tests en conditions réelles et implémentation.
La nouvelle implémentation de chunking tire parti de HTTP/2 pour fournir un plus grand nombre de chunks de plus petite taille.
Sous la nouvelle heuristique, les chunks sont créés pour :
- Un chunk minimal pour chaque page.
- Un chunk framework contenant React, ReactDOM, le Scheduler de React, etc.
- Des chunks library pour toute dépendance
node_module
supérieure à 160kb (avant minification/gzip) - Un chunk commons pour le code utilisé sur toutes les pages.
- Autant de chunks partagés (utilisés par 2 pages ou plus) que possible, optimisant pour la taille globale de l'application et la vitesse de chargement initial.
- Le runtime client-side de Next.js.
- Le runtime Webpack.
Voyons ce que cela signifie dans une application réelle :
Un partenaire industriel early-adopter, Barnebys®, a vu une diminution de 23% de la taille globale de son application.
De plus, leur plus gros bundle JS a été réduit de 30% — de 605kB à 425kB — sans aucun changement de code requis.
Un autre partenaire industriel, SumUp®, a vu une diminution de 70% de leur plus gros bundle JS — de 395kB à 122kB — sans aucun changement de code requis.
Plus gros bundle JavaScript
Avant | Après | Delta | |
---|---|---|---|
Barnebys | 605kB | 425kB | 30% plus petit |
SumUp | 395kB | 122kB | 70% plus petit |
Le nouveau comportement de chunking réduit non seulement la taille globale et de chargement initial, mais aussi les navigations client-side successives. Barnebys® a vu une réduction de 87% de la quantité de JavaScript chargée après six (6) navigations de page :
JavaScript chargé par plusieurs transitions client-side
Avant | Après | Delta | |
---|---|---|---|
Barnebys | 136kB | 18kB | 87% plus petit |
Ce nouveau comportement est entièrement rétrocompatible. Mettre à jour vers la dernière version de Next.js est tout ce que vous avez à faire pour bénéficier de cette amélioration de performance.
Routes dynamiques attrape-tout
Avec la sortie de Next.js 9, nous avions introduit les segments de route dynamiques avec pour objectif de simplifier les segments dynamiques dans Next.js sans avoir besoin d'un serveur custom. Cette fonctionnalité a été massivement adoptée par les utilisateurs de Next.js.
Il restait cependant certains cas que la fonctionnalité de segments de route dynamiques ne couvrait pas.
Un de ces cas était les routes attrape-tout. Par exemple, router un wildcard comme /post/**
comme page. Ceci est particulièrement utile quand vous avez une structure imbriquée définie par une source de contenu comme un CMS.
Vous pouvez maintenant créer des routes dynamiques attrape-tout en utilisant la syntaxe [...name]
.
Par exemple, pages/post/[...slug].js
correspondra à /post/a
, /post/a/b
, /post/a/b/c
, etc.
slug
sera fourni dans l'objet query du routeur comme un tableau de parties individuelles du chemin. Ainsi, pour le chemin /post/foo/bar
, l'objet query sera { slug: ['foo', 'bar'] }
.
Communauté
Nous sommes très enthousiastes de voir l'adoption de Next.js continuer à croître :
- Nous avons eu plus de 880 contributeurs indépendants.
- Sur GitHub, le projet a été star plus de 44 000 fois.
- Le répertoire d'exemples contient plus de 220 exemples.
La communauté Next.js compte maintenant plus de 13 800 membres. Rejoignez-nous !
Nous sommes reconnaissants envers notre communauté et tous les retours et contributions externes qui ont aidé à façonner cette release.