Sortie (output)

Lors d'une compilation, Next.js trace automatiquement chaque page et ses dépendances pour déterminer tous les fichiers nécessaires au déploiement d'une version de production de votre application.

Cette fonctionnalité aide à réduire considérablement la taille des déploiements. Auparavant, lors d'un déploiement avec Docker, vous deviez avoir tous les fichiers des dependencies de votre package installés pour exécuter next start. À partir de Next.js 12, vous pouvez utiliser le traçage des fichiers de sortie (Output File Tracing) dans le répertoire .next/ pour n'inclure que les fichiers nécessaires.

De plus, cela élimine le besoin de la cible serverless dépréciée, qui peut causer divers problèmes et crée également des duplications inutiles.

Fonctionnement

Pendant next build, Next.js utilise @vercel/nft pour analyser statiquement les utilisations de import, require et fs afin de déterminer tous les fichiers qu'une page pourrait charger.

Le serveur de production de Next.js est également tracé pour ses fichiers nécessaires et sorti dans .next/next-server.js.nft.json, ce qui peut être exploité en production.

Pour exploiter les fichiers .nft.json générés dans le répertoire de sortie .next, vous pouvez lire la liste des fichiers dans chaque trace qui sont relatifs au fichier .nft.json et les copier vers votre emplacement de déploiement.

Copie automatique des fichiers tracés

Next.js peut automatiquement créer un dossier standalone qui copie uniquement les fichiers nécessaires pour un déploiement en production, y compris certains fichiers dans node_modules.

Pour utiliser cette copie automatique, vous pouvez l'activer dans votre next.config.js :

next.config.js
module.exports = {
  output: 'standalone',
}

Cela créera un dossier à .next/standalone qui peut ensuite être déployé seul sans installer node_modules.

De plus, un fichier minimal server.js est également généré et peut être utilisé à la place de next start. Ce serveur minimal ne copie pas les dossiers public ou .next/static par défaut, car ceux-ci devraient idéalement être gérés par un CDN, bien que ces dossiers puissent être copiés manuellement vers standalone/public et standalone/.next/static, après quoi le fichier server.js les servira automatiquement.

Bon à savoir :

  • next.config.js est lu pendant next build et sérialisé dans le fichier de sortie server.js. Si les options obsolètes serverRuntimeConfig ou publicRuntimeConfig sont utilisées, les valeurs seront spécifiques aux valeurs au moment de la compilation.
  • Si votre projet doit écouter un port ou un nom d'hôte spécifique, vous pouvez définir les variables d'environnement PORT ou HOSTNAME avant d'exécuter server.js. Par exemple, exécutez PORT=8080 HOSTNAME=0.0.0.0 node server.js pour démarrer le serveur sur http://0.0.0.0:8080.
  • Si votre projet utilise l'optimisation d'images avec le loader par défaut, vous devez installer sharp comme dépendance :
Terminal
npm i sharp
Terminal
yarn add sharp
Terminal
pnpm add sharp
Terminal
bun add sharp

Mises en garde

  • Dans les configurations de monorepo, le répertoire du projet est utilisé par défaut pour le traçage. Pour next build packages/web-app, packages/web-app serait la racine de traçage et aucun fichier en dehors de ce dossier ne sera inclus. Pour inclure des fichiers en dehors de ce dossier, vous pouvez définir experimental.outputFileTracingRoot dans votre next.config.js.
packages/web-app/next.config.js
module.exports = {
  experimental: {
    // cela inclut les fichiers de la base du monorepo deux répertoires au-dessus
    outputFileTracingRoot: path.join(__dirname, '../../'),
  },
}
  • Il existe des cas où Next.js peut échouer à inclure les fichiers nécessaires ou inclure incorrectement des fichiers inutilisés. Dans ces cas, vous pouvez utiliser experimental.outputFileTracingExcludes et experimental.outputFileTracingIncludes respectivement dans next.config.js. Chaque configuration accepte un objet avec des globs minimatch pour la clé correspondant à des pages spécifiques et une valeur de tableau avec des globs relatifs à la racine du projet pour inclure ou exclure dans la trace.
next.config.js
module.exports = {
  experimental: {
    outputFileTracingExcludes: {
      '/api/hello': ['./dossier-inutile/**/*'],
    },
    outputFileTracingIncludes: {
      '/api/another': ['./dossier-necessaire/**/*'],
    },
  },
}
  • Actuellement, Next.js ne fait rien avec les fichiers .nft.json générés. Les fichiers doivent être lus par votre plateforme de déploiement, par exemple Vercel, pour créer un déploiement minimal. Dans une future version, une nouvelle commande est prévue pour utiliser ces fichiers .nft.json.

turbotrace expérimental

Le traçage des dépendances peut être lent car il nécessite des calculs et analyses très complexes. Nous avons créé turbotrace en Rust comme alternative plus rapide et plus intelligente à l'implémentation JavaScript.

Pour l'activer, vous pouvez ajouter la configuration suivante à votre next.config.js :

next.config.js
module.exports = {
  experimental: {
    turbotrace: {
      // contrôle le niveau de log de turbotrace, par défaut `error`
      logLevel?:
      | 'bug'
      | 'fatal'
      | 'error'
      | 'warning'
      | 'hint'
      | 'note'
      | 'suggestions'
      | 'info',
      // contrôle si le log de turbotrace doit contenir les détails de l'analyse, par défaut `false`
      logDetail?: boolean
      // affiche tous les messages de log sans limite
      // turbotrace n'affiche qu'un seul message par catégorie par défaut
      logAll?: boolean
      // contrôle le répertoire de contexte de turbotrace
      // les fichiers en dehors du répertoire de contexte ne seront pas tracés
      // définir `experimental.outputFileTracingRoot` a le même effet
      // si `experimental.outputFileTracingRoot` et cette option sont tous deux définis, `experimental.turbotrace.contextDirectory` sera utilisé
      contextDirectory?: string
      // s'il y a une expression `process.cwd()` dans votre code, vous pouvez définir cette option pour indiquer à `turbotrace` la valeur de `process.cwd()` pendant le traçage.
      // par exemple, le require(process.cwd() + '/package.json') sera tracé comme require('/chemin/vers/cwd/package.json')
      processCwd?: string
      // contrôle l'utilisation maximale de mémoire de `turbotrace`, en `MB`, par défaut `6000`.
      memoryLimit?: number
    },
  },
}