BackRetour au blog

Next.js 7

Après 26 versions canary et 3,4 millions de téléchargements, nous sommes fiers de présenter Next.js 7 prêt pour la production

Après 26 versions canary et 3,4 millions de téléchargements, nous sommes fiers de présenter Next.js 7 prêt pour la production, avec :

Enfin, nous sommes ravis de partager ces nouveautés sur le tout nouveau Nextjs.org.

Améliorations de l'expérience développeur

L'un des objectifs principaux de Next.js est d'offrir les meilleures performances en production avec la meilleure expérience développeur possible. Cette version apporte de nombreuses améliorations significatives aux pipelines de build et de débogage.

Vitesse de compilation

Grâce à webpack 4, Babel 7 et de nombreuses optimisations de notre codebase, Next.js démarre désormais jusqu'à 57 % plus vite en développement.

Grâce à notre nouveau cache de compilation incrémentale, les modifications apportées au code se construisent maintenant 40 % plus vite.

Voici quelques chiffres que nous avons collectés :

6.07.0différence
Temps de démarrage (application basique)1947ms835ms57 % plus rapide
Modification du code (application basique)304ms178ms42 % plus rapide

En bonus, lors du développement et de la construction, vous bénéficierez désormais d'un meilleur feedback en temps réel grâce à webpackbar :

Meilleure gestion des erreurs avec React Error Overlay

Afficher des erreurs précises et utiles est essentiel pour une excellente expérience de développement et de débogage. Jusqu'à présent, nous affichions le message d'erreur et sa pile d'appels. Désormais, nous utilisons react-error-overlay pour enrichir la pile d'appels avec :

  • Des localisations d'erreur précises pour les erreurs côté serveur et client
  • Des surlignages du code source pour fournir du contexte
  • Une pile d'appels complète et détaillée

Voici une comparaison avant/après de nos messages d'erreur :

L'ancien overlay à gauche, react-error-overlay à droite

L'ancien overlay à gauche, react-error-overlay à droite

En bonus, react-error-overlay permet d'ouvrir facilement votre éditeur de texte en cliquant simplement sur un bloc de code spécifique.

Webpack 4

Depuis sa première version, Next.js utilise webpack pour regrouper votre code et réutiliser l'écosystème riche de plugins et d'extensions. Nous sommes ravis d'annoncer que Next.js est désormais propulsé par la dernière version de webpack 4, qui apporte de nombreuses améliorations et corrections de bugs.

Parmi celles-ci, nous obtenons :

  • Support des fichiers sources .mjs
  • Améliorations du découpage de code
  • Meilleur support du tree-shaking (élimination du code inutilisé)

Une autre nouveauté est le support de WebAssembly. Next.js peut même effectuer du rendu côté serveur avec WebAssembly, voici un exemple.

Note : cette mise à jour est entièrement rétrocompatible. Cependant, si vous utilisez des loaders ou plugins webpack personnalisés via next.config.js, vous devrez peut-être les mettre à jour.

Importations CSS

Avec webpack 4, une nouvelle méthode d'extraction des CSS des bundles a été introduite, appelée mini-extract-css-plugin.

@zeit/next-css, @zeit/next-less, @zeit/next-sass, et @zeit/next-stylus utilisent désormais mini-extract-css-plugin.

La nouvelle version de ces plugins Next.js résout 20 problèmes existants liés aux importations CSS. Par exemple, l'importation de CSS dans des import() dynamiques est maintenant supportée :

components/my-dynamic-component.js
import './my-dynamic-component.css';
 
export default function MyDynamicComponent() {
  return <h1>Mon composant dynamique</h1>;
}
pages/index.js
import dynamic from 'next/dynamic'
 
const MyDynamicComponent = dynamic(import('../components/my-dynamic-component'))
 
export default function Index() {
  return () {
    <div>
      <MyDynamicComponent/>
    </div>
  }
}

Une amélioration majeure est que vous n'avez plus besoin d'ajouter ceci dans pages/_document.js :

<link rel="stylesheet" href="/_next/static/style.css" />

À la place, Next.js injecte automatiquement le fichier CSS. En production, Next.js ajoute également automatiquement un hash de contenu à l'URL CSS, afin que si des modifications sont apportées, vos utilisateurs finaux n'obtiennent jamais de versions obsolètes du fichier et puissent bénéficier d'un cache permanent immuable.

En résumé, tout ce que vous avez à faire pour supporter l'importation de fichiers .css dans votre projet Next.js est d'enregistrer simplement le plugin withCSS dans votre next.config.js :

const withCSS = require('@zeit/next-css');
module.exports = withCSS({
  /* ma configuration next */
});

Importations dynamiques standardisées

Next.js supporte les importations dynamiques via next/dynamic depuis la version 3.

En tant qu'early adopters de cette technologie, nous avons dû écrire notre propre solution pour gérer import().

En conséquence, Next.js commençait à diverger du support introduit plus tard par webpack et certaines fonctionnalités manquaient.

Pour cette raison, Next.js ne supportait pas certaines fonctionnalités de import() introduites par webpack.

Par exemple, il n'était pas possible de nommer et regrouper manuellement certains fichiers ensemble :

import(/* webpackChunkName: 'my-chunk' */ '../lib/my-library');

Un autre exemple était l'utilisation de import() sans être enveloppé dans le module next/dynamic.

À partir de Next.js 7, nous n'altérons plus le comportement par défaut de import(). Cela signifie que vous obtenez un support complet de import() prêt à l'emploi.

Ce changement est également entièrement rétrocompatible. Utiliser un composant dynamique reste aussi simple que :

pages/index.js
import dynamic from 'next/dynamic';
 
const MyComponent = dynamic(import('../components/my-component'));
 
export default function Index() {
  return (
    <div>
      <MyComponent />
    </div>
  );
}

Ce que fait cet exemple est de créer un nouveau fichier JavaScript pour my-component et de ne le charger que lorsque <MyComponent /> est rendu.

Plus important encore, s'il n'est pas rendu, la balise <script> n'est pas incluse dans la charge utile HTML initiale.

Pour simplifier davantage notre codebase et utiliser l'excellent écosystème React, dans Next.js 7 next/dynamic a été réécrit pour utiliser react-loadable en arrière-plan (avec quelques modifications mineures). Cela introduit également deux excellentes nouvelles fonctionnalités pour les composants dynamiques :

  • Des timeouts utilisant l'option timeout sur next/dynamic
  • Un délai pour le composant de chargement, utilisant l'option delay sur next/dynamic. Ce délai permet à votre composant loading d'attendre un certain temps avant d'afficher l'état de chargement, par exemple si l'importation est très rapide.

Babel 7

Next.js 6 avait introduit Babel 7 alors qu'il était encore en version bêta. Depuis, la version stable de Babel 7 a été publiée, et Next.js 7 utilise maintenant cette version.

Pour une liste complète des changements, vous pouvez vous référer aux notes de version de Babel.

Parmi les principales fonctionnalités :

  • Support de TypeScript, pour Next.js vous pouvez utiliser @zeit/next-typescript
  • Support de la syntaxe Fragment <>
  • Support de babel.config.js
  • Propriété overrides pour appliquer des presets/plugins uniquement à un sous-ensemble de fichiers ou répertoires

Si vous n'avez pas de configuration Babel personnalisée dans votre projet Next.js, il n'y a aucun changement cassant.

Si vous avez une configuration Babel personnalisée, vous devez mettre à jour les plugins/presets personnalisés respectifs vers leur dernière version.

Si vous effectuez une mise à jour depuis une version antérieure à Next.js 6, vous pouvez utiliser l'excellent outil babel-upgrade.

En plus de la mise à jour vers Babel 7, le preset Babel de Next.js (next/babel) définit maintenant par défaut l'option modules sur commonjs lorsque NODE_ENV est défini sur test.

Cette option de configuration était souvent la seule raison de créer un .babelrc personnalisé dans un projet Next.js :

.babelrc
{
  "env": {
    "development": {
      "presets": ["next/babel"]
    },
    "production": {
      "presets": ["next/babel"]
    },
    "test": {
      "presets": [["next/babel", { "preset-env": { "modules": "commonjs" } }]]
    }
  }
}

Avec Next.js 7, cela devient :

.babelrc
{
  "presets": ["next/babel"]
}

À ce stade, le .babelrc peut être supprimé, car Next.js utilisera automatiquement next/babel lorsqu'il n'y a pas de configuration Babel.

Charge utile HTML initiale réduite

Comme Next.js pré-rend le HTML, il enveloppe les pages dans une structure par défaut avec <html>, <head>, <body> et les fichiers JavaScript nécessaires pour rendre la page.

Cette charge utile initiale était auparavant d'environ 1,62 kB. Avec Next.js 7, nous avons optimisé la charge utile HTML initiale, elle est maintenant de 1,5 kB, une réduction de 7,4 %, rendant vos pages plus légères.

6.07.0différence
Taille du document (rendu serveur)1,62 kB1,50 kB7,4 % plus petit

Les principales façons dont nous avons réduit la taille sont :

  • La div __next-error est supprimée
  • Les scripts inline sont minifiés, dans une future version ils seront complètement supprimés
  • Compilation des propriétés inutilisées de __NEXT_DATA__ lorsqu'elles ne sont pas utilisées, par exemple les propriétés nextExport et assetPrefix.

Support des CDN statiques

Dans Next.js 5, nous avons introduit le support de assetPrefix, une façon de faire en sorte que Next.js charge automatiquement les assets depuis un certain emplacement, généralement un CDN. Cette option fonctionne bien si votre CDN supporte le proxying, vous demandez une URL comme :

https://cdn.example.com/_next/static/<buildid>/pages/index.js

Typiquement, le CDN vérifie s'il a le fichier dans son cache, ou sinon le demande directement à l'origine.

Le proxying des assets est exactement comment fonctionne le Edge Network.

Cependant, certaines solutions nécessitent de pré-uploader un répertoire directement dans le CDN. Le problème est que la structure d'URL de Next.js ne correspondait pas à la structure de dossier à l'intérieur du dossier .next. Par exemple, notre exemple précédent :

https://cdn.example.com/_next/static/<buildid>/pages/index.js
// correspondait à :
.next/page/index.js

Avec Next.js 7, nous avons changé la structure de répertoire de .next pour correspondre à la structure d'URL :

https://cdn.example.com/_next/static/<buildid>/pages/index.js
// correspond maintenant à :
.next/static/<buildid>/pages/index.js

Bien que nous recommandions d'utiliser un CDN de type proxying, cette nouvelle structure permet aux utilisateurs d'un autre type de CDN d'uploader le répertoire .next vers leur CDN.

Styled JSX v3

Nous sommes ravis de présenter styled-jsx 3, la solution CSS-in-JS incluse par défaut dans Next.js est maintenant prête pour React Suspense.

Une chose qui n'était souvent pas claire était comment styliser un composant enfant si ce composant ne faisait pas partie de la portée du composant actuel, par exemple si vous incluiez un composant enfant qui nécessitait des styles spécifiques uniquement lorsqu'il était utilisé à l'intérieur du composant parent :

pages/index.js
const ChildComponent = () => (
  <div>
    <p>du texte</p>
  </div>
);
 
export default function Index() {
  return (
    <div>
      <ChildComponent />
      <style jsx>{`
        p {
          color: black;
        }
      `}</style>
    </div>
  );
}

Le code ci-dessus essaie de sélectionner la balise p mais ne fonctionne pas car les styles styled-jsx sont limités au composant actuel, ils ne fuient pas dans les composants enfants. Une façon de contourner ce problème était d'utiliser la méthode :global, en supprimant le préfixe de la balise p. Cependant, cela introduit un nouveau problème, à savoir que les styles fuient à travers la page.

Dans styled-jsx 3, ce problème a été résolu en introduisant une nouvelle API, css.resolve, qui générera le className et les balises <style> (la propriété styles) pour la chaîne styled-jsx donnée :

pages/index.js
import css from 'styled-jsx/css';
 
const ChildComponent = ({ className }) => (
  <div>
    <p className={className}>du texte</p>
  </div>
);
 
const { className, styles } = css.resolve`
  p {
    color: black;
  }
`;
 
export default function Index() {
  return (
    <div>
      <ChildComponent className={className} />
      {styles}
    </div>
  );
}

Cette nouvelle API permet de transmettre de manière transparente des styles personnalisés aux composants enfants.

Comme il s'agit d'une version majeure pour styled-jsx, il y a un changement cassant qui améliore la taille des bundles si vous utilisez styles-jsx/css. Dans styled-jsx 2, nous générions une version "scoped" et "global" des styles externes, même lorsque seule la version "scoped" était utilisée, nous incluions toujours la version "global" de ces styles externes.

Avec styled-jsx 3, les styles globaux doivent être tagués avec css.global au lieu de css, afin que styled-jsx puisse optimiser la taille du bundle.

Pour tous les changements, veuillez vous référer aux notes de version.

Contexte React avec SSR entre App et Pages

À partir de Next.js 7, nous supportons maintenant la nouvelle API de contexte React entre pages/_app.js et les composants de page.

Auparavant, il n'était pas possible d'utiliser le contexte React entre les pages côté serveur. La raison était que webpack maintient un cache de module interne au lieu d'utiliser require.cache. Nous avons écrit un plugin webpack personnalisé qui modifie ce comportement pour partager les instances de module entre les pages.

En faisant cela, nous permettons non seulement l'utilisation du nouveau contexte React, mais nous réduisons également l'empreinte mémoire de Next.js lors du partage de code entre les pages.

6.07.0différence
Utilisation mémoire57,5 MB48,1 MB-16 % mémoire

nextjs.org

En parallèle de la sortie de Next.js 7, nous lançons un nextjs.org complètement repensé.

Blog

L'article de blog que vous êtes en train de lire fait déjà partie de la nouvelle section blog sur nextjs.org. Ce blog sera le nouveau foyer pour les communications liées à Next.js, par exemple les annonces de nouvelles versions.

Le nouveau nextjs.org

Le nouveau nextjs.org

Soyez inspiré

Alors que le nombre d'applications utilisant Next.js ne cesse de croître, nous avions besoin d'un moyen de présenter toutes ces belles applications en un seul aperçu. Découvrez la nouvelle page /showcase :

Soyez inspiré sur nextjs.org/showcase

Soyez inspiré sur nextjs.org/showcase

Cette nouvelle vitrine nous permet d'ajouter continuellement de nouvelles applications construites avec Next.js.

Nous vous invitons à visiter /showcase pour trouver l'inspiration, ou à soumettre votre application utilisant Next.js !

Communauté

Depuis sa première version, Next.js a été utilisé dans tout, des entreprises du Fortune 500 aux blogs personnels. Nous sommes très enthousiastes de voir l'adoption croissante de Next.js.

  • Actuellement, plus de 12 500 domaines publics indexés utilisent Next.js.
  • Nous avons eu plus de 500 contributeurs ayant soumis au moins 1 commit.
  • Sur GitHub, le projet a été mis en favori plus de 29 000 fois.
  • Près de 2200 demandes de pull ont été soumises depuis la première version.

La communauté Next.js compte près de 2000 membres. Rejoignez-nous !