Compilateur Next.js

Le compilateur Next.js, écrit en Rust avec SWC, permet à Next.js de transformer et minifier votre code JavaScript pour la production. Il remplace Babel pour les fichiers individuels et Terser pour la minification des bundles.

La compilation avec le compilateur Next.js est 17 fois plus rapide que Babel et est activée par défaut depuis Next.js version 12. Si vous avez une configuration Babel existante ou utilisez des fonctionnalités non prises en charge, votre application continuera à utiliser Babel au lieu du compilateur Next.js.

Pourquoi SWC ?

SWC est une plateforme extensible basée sur Rust pour la nouvelle génération d'outils de développement rapides.

SWC peut être utilisé pour la compilation, la minification, le bundling et plus encore – et est conçu pour être extensible. C'est un outil que vous pouvez appeler pour effectuer des transformations de code (soit intégrées, soit personnalisées). L'exécution de ces transformations se fait via des outils de plus haut niveau comme Next.js.

Nous avons choisi de construire sur SWC pour plusieurs raisons :

  • Extensibilité : SWC peut être utilisé comme une Crate à l'intérieur de Next.js, sans avoir à forker la bibliothèque ou contourner des contraintes de conception.
  • Performance : Nous avons pu obtenir un rafraîchissement ~3x plus rapide (Fast Refresh) et des builds ~5x plus rapides dans Next.js en passant à SWC, avec encore de la marge pour des optimisations supplémentaires.
  • WebAssembly : Le support de WASM par Rust est essentiel pour supporter toutes les plateformes possibles et permettre le développement Next.js partout.
  • Communauté : La communauté et l'écosystème Rust sont formidables et en pleine croissance.

Fonctionnalités prises en charge

Styled Components

Nous travaillons à porter babel-plugin-styled-components vers le compilateur Next.js.

Premièrement, mettez à jour vers la dernière version de Next.js : npm install next@latest. Ensuite, mettez à jour votre fichier next.config.js :

next.config.js
module.exports = {
  compiler: {
    styledComponents: true,
  },
}

Pour des cas d'utilisation avancés, vous pouvez configurer des propriétés individuelles pour la compilation de styled-components.

Note : Les transformations ssr et displayName sont les principales exigences pour utiliser styled-components dans Next.js.

next.config.js
module.exports = {
  compiler: {
    // voir https://styled-components.com/docs/tooling#babel-plugin pour plus d'informations sur les options.
    styledComponents: {
      // Activé par défaut en développement, désactivé en production pour réduire la taille des fichiers,
      // définir ceci remplacera le comportement par défaut pour tous les environnements.
      displayName?: boolean,
      // Activé par défaut.
      ssr?: boolean,
      // Activé par défaut.
      fileName?: boolean,
      // Vide par défaut.
      topLevelImportPaths?: string[],
      // Par défaut ["index"].
      meaninglessFileNames?: string[],
      // Activé par défaut.
      minify?: boolean,
      // Activé par défaut.
      transpileTemplateLiterals?: boolean,
      // Vide par défaut.
      namespace?: string,
      // Désactivé par défaut.
      pure?: boolean,
      // Activé par défaut.
      cssProp?: boolean,
    },
  },
}

Jest

Le compilateur Next.js transpile vos tests et simplifie la configuration de Jest avec Next.js, notamment :

  • Le mock automatique des imports .css, .module.css (et leurs variantes .scss), et des images
  • Configuration automatique de transform avec SWC
  • Chargement de .env (et toutes ses variantes) dans process.env
  • Ignore node_modules pour la résolution et transformation des tests
  • Ignore .next pour la résolution des tests
  • Charge next.config.js pour les flags activant les transformations expérimentales SWC

Premièrement, mettez à jour vers la dernière version de Next.js : npm install next@latest. Ensuite, mettez à jour votre fichier jest.config.js :

jest.config.js
const nextJest = require('next/jest')

// Fournir le chemin vers votre application Next.js pour permettre le chargement de next.config.js et des fichiers .env
const createJestConfig = nextJest({ dir: './' })

// Toute configuration personnalisée que vous souhaitez passer à Jest
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}

// createJestConfig est exporté de cette manière pour garantir que next/jest peut charger la configuration Next.js, qui est asynchrone
module.exports = createJestConfig(customJestConfig)

Relay

Pour activer le support de Relay :

next.config.js
module.exports = {
  compiler: {
    relay: {
      // Doit correspondre à relay.config.js
      src: './',
      artifactDirectory: './__generated__',
      language: 'typescript',
      eagerEsModules: false,
    },
  },
}

Bon à savoir : Dans Next.js, tous les fichiers JavaScript du répertoire pages sont considérés comme des routes. Donc, pour relay-compiler, vous devrez spécifier les paramètres de configuration artifactDirectory en dehors de pages, sinon relay-compiler générera des fichiers à côté du fichier source dans le répertoire __generated__, et ce fichier sera considéré comme une route, ce qui cassera les builds de production.

Supprimer les propriétés React

Permet de supprimer les propriétés JSX. Souvent utilisé pour les tests. Similaire à babel-plugin-react-remove-properties.

Pour supprimer les propriétés correspondant à l'expression régulière par défaut ^data-test :

next.config.js
module.exports = {
  compiler: {
    reactRemoveProperties: true,
  },
}

Pour supprimer des propriétés personnalisées :

next.config.js
module.exports = {
  compiler: {
    // Les regex définis ici sont traités en Rust donc la syntaxe est différente des
    // `RegExp` JavaScript. Voir https://docs.rs/regex.
    reactRemoveProperties: { properties: ['^data-custom$'] },
  },
}

Supprimer les console

Cette transformation permet de supprimer tous les appels console.* dans le code de l'application (pas dans node_modules). Similaire à babel-plugin-transform-remove-console.

Supprimer tous les appels console.* :

next.config.js
module.exports = {
  compiler: {
    removeConsole: true,
  },
}

Supprimer les sorties console.* sauf console.error :

next.config.js
module.exports = {
  compiler: {
    removeConsole: {
      exclude: ['error'],
    },
  },
}

Décorateurs legacy

Next.js détectera automatiquement experimentalDecorators dans jsconfig.json ou tsconfig.json. Les décorateurs legacy sont couramment utilisés avec des versions plus anciennes de bibliothèques comme mobx.

Ce flag est uniquement supporté pour la compatibilité avec les applications existantes. Nous ne recommandons pas d'utiliser les décorateurs legacy dans de nouvelles applications.

Premièrement, mettez à jour vers la dernière version de Next.js : npm install next@latest. Ensuite, mettez à jour votre fichier jsconfig.json ou tsconfig.json :

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

importSource

Next.js détectera automatiquement jsxImportSource dans jsconfig.json ou tsconfig.json et l'appliquera. Ceci est couramment utilisé avec des bibliothèques comme Theme UI.

Premièrement, mettez à jour vers la dernière version de Next.js : npm install next@latest. Ensuite, mettez à jour votre fichier jsconfig.json ou tsconfig.json :

{
  "compilerOptions": {
    "jsxImportSource": "theme-ui"
  }
}

Emotion

Nous travaillons à porter @emotion/babel-plugin vers le compilateur Next.js.

Premièrement, mettez à jour vers la dernière version de Next.js : npm install next@latest. Ensuite, mettez à jour votre fichier next.config.js :

next.config.js

module.exports = {
  compiler: {
    emotion: boolean | {
      // Par défaut true. Sera désactivé lorsque le type de build est production.
      sourceMap?: boolean,
      // Par défaut 'dev-only'.
      autoLabel?: 'never' | 'dev-only' | 'always',
      // Par défaut '[local]'.
      // Valeurs autorisées : `[local]` `[filename]` et `[dirname]`
      // Cette option ne fonctionne que lorsque autoLabel est défini sur 'dev-only' ou 'always'.
      // Elle vous permet de définir le format du label résultant.
      // Le format est défini via une chaîne où les parties variables sont entre crochets [].
      // Par exemple labelFormat: "my-classname--[local]", où [local] sera remplacé par le nom de la variable à laquelle le résultat est assigné.
      labelFormat?: string,
      // Par défaut undefined.
      // Cette option vous permet d'indiquer au compilateur quels imports il doit
      // examiner pour déterminer ce qu'il doit transformer, donc si vous réexportez
      // les exports d'Emotion, vous pouvez toujours utiliser les transformations.
      importMap?: {
        [packageName: string]: {
          [exportName: string]: {
            canonicalImport?: [string, string],
            styledBaseImport?: [string, string],
          }
        }
      },
    },
  },
}

Minification

Le compilateur swc de Next.js est utilisé pour la minification par défaut depuis la v13. C'est 7 fois plus rapide que Terser.

Bon à savoir : À partir de la v15, la minification ne peut plus être personnalisée via next.config.js. Le support du flag swcMinify a été supprimé.

Transpilation de modules

Next.js peut transpiler et bundler automatiquement des dépendances depuis des packages locaux (comme des monorepos) ou des dépendances externes (node_modules). Cela remplace le package next-transpile-modules.

next.config.js
module.exports = {
  transpilePackages: ['@acme/ui', 'lodash-es'],
}

Modularisation des imports

Cette option a été remplacée par optimizePackageImports dans Next.js 13.5. Nous recommandons de mettre à jour pour utiliser la nouvelle option qui ne nécessite pas de configuration manuelle des chemins d'import.

Define (Remplacement de variables pendant le build)

L'option define vous permet de remplacer statiquement des variables dans votre code au moment du build. L'option prend un objet comme paires clé-valeur, où les clés sont les variables à remplacer par les valeurs correspondantes.

Utilisez le champ compiler.define dans next.config.js pour définir des variables pour tous les environnements (serveur, edge et client). Ou utilisez compiler.defineServer pour définir des variables uniquement pour le code côté serveur (serveur et edge) :

next.config.js
module.exports = {
  compiler: {
    define: {
      MY_VARIABLE: 'my-string',
      'process.env.MY_ENV_VAR': 'my-env-var',
    },
    defineServer: {
      MY_SERVER_VARIABLE: 'my-server-var',
    },
  },
}

Hooks du cycle de vie du build

Le compilateur Next.js supporte des hooks de cycle de vie qui vous permettent d'exécuter du code personnalisé à des moments spécifiques du processus de build. Actuellement, le hook suivant est supporté :

runAfterProductionCompile

Une fonction hook qui s'exécute après la fin de la compilation du build de production, mais avant l'exécution des tâches post-compilation comme la vérification des types et la génération des pages statiques. Ce hook donne accès aux métadonnées du projet incluant le répertoire du projet et le répertoire de sortie du build, ce qui le rend utile pour les outils tiers afin de collecter les sorties de build comme les sourcemaps.

next.config.js
module.exports = {
  compiler: {
    runAfterProductionCompile: async ({ distDir, projectDir }) => {
      // Votre code personnalisé ici
    },
  },
}

Le hook reçoit un objet avec les propriétés suivantes :

  • distDir: Le répertoire de sortie du build (par défaut .next)
  • projectDir: Le répertoire racine du projet

Fonctionnalités expérimentales

Profilage des traces SWC

Vous pouvez générer les traces internes de transformation de SWC au format trace event de chromium.

next.config.js
module.exports = {
  experimental: {
    swcTraceProfiling: true,
  },
}

Une fois activé, swc générera une trace nommée swc-trace-profile-${timestamp}.json sous .next/. Le visualiseur de traces de chromium (chrome://tracing/, https://ui.perfetto.dev/), ou un visualiseur de flamegraph compatible (https://www.speedscope.app/) peut charger et visualiser les traces générées.

Plugins SWC (expérimental)

Vous pouvez configurer la transformation SWC pour utiliser le support expérimental des plugins SWC écrits en wasm afin de personnaliser le comportement de transformation.

next.config.js
module.exports = {
  experimental: {
    swcPlugins: [
      [
        'plugin',
        {
          ...pluginOptions,
        },
      ],
    ],
  },
}

swcPlugins accepte un tableau de tuples pour configurer les plugins. Un tuple pour le plugin contient le chemin vers le plugin et un objet pour la configuration du plugin. Le chemin vers le plugin peut être un nom de package npm ou un chemin absolu vers le binaire .wasm lui-même.

Fonctionnalités non prises en charge

Lorsque votre application a un fichier .babelrc, Next.js reviendra automatiquement à l'utilisation de Babel pour transformer les fichiers individuels. Cela assure une compatibilité descendante avec les applications existantes qui utilisent des plugins Babel personnalisés.

Si vous utilisez une configuration Babel personnalisée, partagez votre configuration. Nous travaillons à porter autant de transformations Babel couramment utilisées que possible, ainsi qu'à supporter les plugins dans le futur.

Historique des versions

VersionChangements
v13.1.0Transpilation de modules et Modularisation des imports stables.
v13.0.0Minification SWC activée par défaut.
v12.3.0Minification SWC stable.
v12.2.0Support expérimental des plugins SWC ajouté.
v12.1.0Ajout du support pour Styled Components, Jest, Relay, Suppression des propriétés React, Décorateurs legacy, Suppression des console, et jsxImportSource.
v12.0.0Compilateur Next.js introduit.