PRNext 0.1.19 : compiler au premier usage, préserver l’état
Un éditeur ouvert sur une seule page ne devrait pas imposer son travail de compilation à chaque démarrage. Un formulaire en cours ne devrait pas disparaître parce qu’une modification de code arrive pendant sa soumission. PRNext 0.1.19-alpha traite ces situations avec une compilation client différée, un cycle de développement plus précis et une meilleure coordination entre Server Actions et Fast Refresh.
Cette version donne aussi davantage de contexte avant une migration et un exemple complet pour éprouver une application avec comptes, base de données et authentification. Voici ce qui change dans votre projet, comment activer les options utiles et où leurs limites restent importantes.
Garder le travail en cours pendant une modification de code
Imaginez un tableau de bord avec un filtre dans le layout et un formulaire qui appelle une Server Action. Vous enregistrez un composant pendant que la réponse du formulaire arrive. PRNext coordonne ces deux opérations pour conserver le layout monté lorsque la mise à jour est compatible, au lieu de confondre un renouvellement des références d’action avec une raison de recommencer toute la page.
Les actions dont le code ne change pas conservent leur identité pendant la session de développement, y compris avec Cache Components. Une action modifiée reçoit une nouvelle identité. Les builds de production gardent des identités indépendantes. Une ancienne réponse Flight ne peut pas remplacer un rendu appartenant à une génération plus récente, et l’erreur d’une action reste observable même si une navigation remplace son rendu.
La mutation et son affichage restent deux opérations distinctes. Une interaction plus récente peut rendre un ancien affichage inutile, mais PRNext ne soumet pas à nouveau la mutation. Les modifications incompatibles, certains changements de configuration et un rechargement complet peuvent toujours réinitialiser l’état en mémoire.
Compiler un outil lourd quand vous l’ouvrez
Un import dynamique ordinaire produit un chunk pendant la compilation, même si son téléchargement attend une interaction. L’option experimental.lazyDynamicImports va plus loin en développement : elle laisse les cibles client éligibles hors du graphe navigateur initial et attend leur premier usage pour les transformer et les compiler.
Activez cette option dans une application App Router utilisant le compilateur natif. Un éditeur, un visualiseur ou un panneau rarement ouvert constitue un bon point de comparaison. L’option reste désactivée par défaut.
export default {
experimental: {
lazyDynamicImports: true
}
};Le premier accès paie le coût de compilation du sous-graphe. Ses fichiers sont préparés dans un espace privé, puis publiés complets. Ses styles sont chargés avant la résolution de l’import. Après activation, le module participe aux mises à jour JavaScript et CSS. Les dépendances ESM déjà chargées conservent leur identité et leurs liaisons vivantes ; deux importeurs partagent aussi le même objet JSON.
Le bénéfice recherché est de déplacer du travail hors du démarrage lorsque votre parcours n’utilise pas cet outil. Il faut mesurer ce démarrage et le délai du premier accès ensemble. L’option ne modifie ni les chunks de production ni le comportement du rendu serveur.
Un exemple avec un éditeur réservé au navigateur
Un composant next/dynamic avec ssr: false permet de réserver l’éditeur au navigateur. Dans cet exemple, le composant n’est demandé qu’après l’ouverture du panneau. Avec la compilation différée activée, son code client éligible attend cette utilisation.
'use client';
import { useState } from 'react';
import dynamic from 'next/dynamic';
const Editor = dynamic(() => import('./editor'), {
ssr: false,
loading: () => <p>Chargement de l’éditeur…</p>
});
export default function EditorPanel() {
const [open, setOpen] = useState(false);
return open
? <Editor />
: <button onClick={() => setOpen(true)}>Ouvrir l’éditeur</button>;
}Le périmètre initial exclut les hooks webpack et les loaders personnalisés. Les imports calculés, les attributs d’import et les chemins littéraux contenant ? ou # gardent la compilation ordinaire. Un suffixe introduit par un alias ou une dépendance dans un graphe différé provoque une erreur explicite. Une dépendance CommonJS partagée qui ne peut pas préserver son identité et une nouvelle Server Action découverte uniquement dans ce graphe demandent aussi le chemin ordinaire ou un import statique adapté.
Les styles activés restent chargés pendant la génération de développement, y compris avec des routes parallèles. Préférez des CSS Modules ou des sélecteurs propres à l’outil. Le mécanisme exige des liens physiques sur le système de fichiers de la génération ; désactivez l’option si cet environnement ne les permet pas.
Modifier une feuille de style sans recopier le build JavaScript
Une modification CSS compatible reconstruit les bundles concernés et publie une petite génération de styles au-dessus de la génération JavaScript courante. PRNext conserve les ressources encore utilisées, notamment les images, les polices et les source maps, sans parcourir ni recopier tous les fichiers JavaScript pour cette mise à jour.
Si vous modifiez le style d’un panneau, puis plusieurs fois celui d’un autre, les ressources modifiées du premier restent disponibles dans le catalogue borné des styles. Les ressources inchangées restent accessibles dans la génération de base. Une provenance incomplète, un catalogue trop grand ou un changement incompatible déclenche le repli vers la compilation complète.
Les graphes incrémentaux répartissent aussi leur budget entre compilation principale et styles. Les styles peuvent emprunter de la capacité disponible, sans évincer indéfiniment les graphes principaux lorsqu’un projet possède de nombreux scopes CSS. Les limites restent globales et le travail est libéré à la fermeture de la session.
Sur macOS, une notification de dossier peut regrouper plusieurs changements. PRNext vérifie alors les fichiers du sous-arbre concerné pour détecter une modification profonde, en développement comme avec build --watch. Si cette vérification reste incomplète, il signale une erreur récupérable et conserve le dernier build, sans lancer une boucle de compilation.
Comprendre une incompatibilité avant de changer de moteur
Un import next/* pris en charge dans votre code peut cacher une dépendance qui utilise une API privée différente. L’audit de migration suit les imports statiques réellement atteints jusque dans les paquets installés. Il tient compte des contextes navigateur, Node et React Server Components et donne le fichier, la ligne et la chaîne d’imports qui conduisent au diagnostic.
Les frontières use server restent des frontières serveur, même lorsqu’un Client Component les atteint par une réexportation. Une dépendance navigateur sur une API Node est examinée avec les mappings browser et les implémentations installées, plutôt que d’être déclarée compatible sur la seule présence du paquet.
Depuis un projet avec la version de PRNext voulue déjà installée, commencez par les contrôles sans application de migration :
npx --no-install prnext migrate --dry-run
npx --no-install prnext migrate --check --jsonLe rapport distingue ce qui a été inspecté de ce qui reste inconnu. Un import calculé, la sortie d’un loader ou une limite de parcours ne devient pas un succès implicite. L’audit ne lance pas les modules des dépendances inspectées, mais l’évaluation de la configuration peut exécuter du code du projet. Il ne constitue donc ni un bac à sable pour du code inconnu ni une certification de compatibilité. Une compilation réelle et vos parcours métier restent nécessaires.
Passer d’une page de démonstration à une application avec comptes
L’exemple saas-reference réunit Better Auth, PostgreSQL, Drizzle et next-intl dans une application française et anglaise. Chaque compte possède ses notes. Le tableau de bord vérifie la session, et chaque mutation vérifie à nouveau l’utilisateur et la propriété de la donnée. Masquer un bouton ou protéger uniquement une page ne suffit pas.
Les formulaires d’authentification appliquent des quotas atomiques partagés dans PostgreSQL avant le calcul coûteux des mots de passe. Les parcours de qualification exercent la révocation des sessions, les refus CSRF et les callbacks OpenID Connect invalides, avec un fournisseur local contrôlé et un passage HTTPS qui vérifie les cookies sécurisés.
La même application est testée après déplacement de sa sortie standalone, avec deux workers et suppression de la source d’origine. Cet exemple sert de point de départ vérifiable. Les règles d’accès, de récupération de compte, de vérification et de limitation des abus restent à adapter au produit. En déploiement, le backend doit rester privé derrière un proxy de confiance qui remplace les en-têtes de transfert.
Adopter la version avec les bons contrôles
Après une mise à jour, contrôlez la version réellement installée et l’alignement des dépendances React, puis reconstruisez et redémarrez l’application. Si vous migrez depuis Next.js, gardez le rapport d’audit et vérifiez vos routes authentifiées, les formulaires, les styles et les parcours de navigation. Une option expérimentale doit aussi être comparée dans votre propre projet avant d’être conservée.
PRNext reste une alpha avec une compatibilité Next.js partielle. La validation fonctionnelle couvre Linux, macOS et Windows, ainsi que Chromium, Firefox et WebKit. Ces contrôles ne démontrent pas un gain général de performances. Une campagne historique reste inconclusive en raison d’observations de processus incomplètes ; elle ne permet pas de conclure sur les performances de cette version. Les anciens échecs Windows EPERM pendant la publication atomique de l’état de développement restent documentés, sans cause ni correction spécifique démontrée.
Le point de départ utile est un parcours représentatif : ouvrir une route froide, modifier son style, soumettre un formulaire et revenir sur une page déjà visitée. Vous vérifiez ainsi ce que cette version change pour votre application, avec ses dépendances, son authentification et ses contraintes de déploiement.