Dans un précédent article, je vous ai parlé de la migration de Symfony 5 vers Symfony 6, en détaillant les étapes clés pour réussir cette transition en toute sérénité. Aujourd’hui, je vais vous accompagner dans une nouvelle étape importante : la migration de Symfony 6 vers Symfony 7. Cette mise à jour, tout aussi cruciale, apporte son lot de nouveautés, de bonnes pratiques et de points d’attention que nous allons explorer ensemble

Tous les 6 mois, en mai et en novembre, une nouvelle version mineure de Symfony est publiée, comme la 6.1 ou la 6.2. Ce sont ces versions qui introduisent de nouvelles fonctionnalités. Donc, c’est tout à fait normal de découvrir Symfony 6.3 ou les incroyables nouveautés de Symfony 6.4.

Ensuite, chaque version en « .4 », comme la 6.4, est publiée le même jour que la version « .0 » de la prochaine version majeure, comme la 7.0. Oui, Symfony 6.4 et Symfony 7.0 sont sortis exactement le même jour.

La seule différence est qu’en Symfony 7.0, tous les chemins de code obsolètes (deprecated) ont été supprimés.

Enfin, vers la fin de votre fichier composer.json, sous la section extra.symfony.require, assurez-vous également de mettre à jour la version vers 6.4.*. C’est une optimisation pour Composer qui lui indique de ne s’occuper que des versions Symfony 6.4.

symfony composer up 'symfony/*'

Cette commande garantit que toutes vos bibliothèques Symfony sont mises à jour à la version 6.4, préparant ainsi le terrain pour la migration vers Symfony 7. Une fois cette étape terminée, il est recommandé de vérifier le bon fonctionnement de votre application et de corriger toute dépréciation signalée par Symfony.

Comme vous le savez probablement, chaque fois que nous installons un nouveau package, ce package peut être accompagné d’une recette (recipes) qui effectue des actions telles que l’ajout de fichiers de configuration, la modification de certains fichiers comme .env, ou l’ajout d’autres fichiers. Au fil du temps, Symfony met à jour ces recipes. Parfois, ces mises à jour sont mineures… comme l’ajout d’un commentaire dans un fichier de configuration. Mais d’autres fois, elles sont plus importantes, comme le renommage de clés de configuration pour s’adapter aux changements dans Symfony lui-même. Et bien que vous ne soyez pas obligé de mettre à jour vos recipes, c’est un excellent moyen de garder votre application conforme aux standards d’une application Symfony. C’est aussi un moyen gratuit de mettre à jour le code obsolète. ===> symfony composer recipes

symfony composer recipes:update

Cette commande vérifie quelles recipes sont installées dans votre projet et recherche de nouvelles versions. Lorsque vous choisissez une recipe à mettre à jour, elle génère un diff entre la version originale et la nouvelle version puis applique ces changements.

Vous devriez toujours vérifier attentivement les différences pour éviter de perdre toute configuration personnalisée

C’est à nous de gérer les conflits pour chaque bundle choisi.

Après la mise à jour de plusieurs recipes, en changeant de page, nous avons rencontré l’erreur suivante.

SensioFrameworkExtraBundle nous offrait toutes sortes de fonctionnalités, comme l’annotation @Route, security annotation, et le param converter. Toutes ces fonctionnalités reposaient sur le système d’annotations, qui a été remplacé par les attributs natifs de PHP. Lorsque nous avons désactivé ces annotations (config/framework.yaml), le bundle n’a pas apprécié.

Mais ce n’est pas un problème ! Toutes ces fonctionnalités pratiques ont trouvé une nouvelle maison dans le cœur de Symfony. Il est donc temps de supprimer le bundle SensioFrameworkExtraBundle.

symfony composer remove sensio/framework-extra-bundle

Pour vous aider, Symfony propose une excellente page de documentation intitulée Symfony Attributes Overview. Elle répertorie tous les attributs PHP disponibles dans Symfony. Par exemple, le SensioFrameworkExtraBundle proposait une annotation Security. Désormais, Symfony offre l’attribut IsGranted que vous pouvez utiliser à la place.

Ainsi, si vous utilisez encore des éléments de l’ancien système, identifiez leur équivalent dans le nouveau et procédez à la mise à jour.

J’aimerais vous parler du Symfony Twig Bundle. Lors de la mise à jour des recettes, vous allez constater un changement dans base.html.twig : les fonctions encore_entry_link_tags() et encore_entry_script_tags() ont été supprimées. Pourquoi ?

Une grande nouveauté récente dans l’univers du frontend de Symfony est le StimulusBundle. En soi, ce n’est pas un changement majeur. Cependant, son introduction a entraîné une réorganisation des recipes. Certaines modifications qui se trouvaient auparavant dans la recipe d’un package ont été déplacées vers une autre.

Par exemple, ces lignes faisaient autrefois partie de la recipe de TwigBundle, mais elles ont été transférées dans celle de WebpackEncoreBundle. Ainsi, lors de la mise à jour de la recette de TwigBundle, il peut sembler que ces lignes doivent être supprimées.

Le plus grand changement dans l’univers d’Encore a été l’introduction du StimulusBundle. En lien avec cela, dans le fichier composer.json, le package symfony/webpack-encore-bundle dispose désormais d’une nouvelle version majeure. Modifiez sa version en ^2.0.

symfony composer up

Alors, qu’est-ce qui a changé entre la version 1 et la version 2 de WebpackEncoreBundle ? Une seule chose : les fonctions utilitaires Twig liées à Stimulus – comme stimulus_controller() – ont été supprimées de ce bundle (WebpackEncoreBundle) et déplacées dans le nouveau StimulusBundle. Rien de bien compliqué.

Le vrai défi réside dans ce que j’ai mentionné précédemment : l’introduction de ce nouveau bundle a entraîné une réorganisation de plusieurs parties des recipes entre différents packages. Par exemple, en plus du déplacement des fonctions Twig encore_entry() dans la recipe de WebpackEncoreBundle, certains fichiers – comme assets/controllers.json – ont été transférés de la recipe de WebpackEncoreBundle à celle de StimulusBundle.

C’est une bonne chose dans l’ensemble : la nouvelle organisation est plus claire, avec les fichiers liés à Stimulus regroupés dans la recipe de son propre bundle. Mais cela complique un peu les choses lorsqu’on met à jour les recipes.

symfony composer recipes:update

Il faut faire très attention lors de la mise à jour de la recette de webpack-encore-bundle une 2eme fois 🙂

Des conflits sont apparus. Beaucoup des fichiers en question faisaient partie de la recipe de WebpackEncoreBundle, mais en ont été déplacés. Ainsi, lors de la mise à jour de la recipe, cela donne l’impression qu’une multitude de choses doivent être supprimées.

  • Dans assets/app.js, le fichier n’a pas été supprimé, mais son contenu est en train d’être effacé. Conservez-le tel qu’il était auparavant.
  • Passons maintenant à package.json. Là aussi, c’est un peu la même situation : des suppressions sont proposées. Ne laissez pas cela arriver ! Conservez notre code.

Ensuite, voyons ce qui reste. Le système propose de supprimer assets/bootstrap.js : nous ne le voulons pas. Il veut également supprimer controllers.json, ce que nous ne voulons pas non plus. En fait, nous ne voulons d’aucun de ces changements.

La seule modification qui nous intéresse réellement se trouve dans base.html.twig. Et voilà ! Les fonctions encore_entry_link_tags() et encore_entry_script_tags() y sont réintroduites.

Enfin, dans le fichier webpack.config.js, il est proposé de supprimer enableStimulusBridge(). Comme nous utilisons Stimulus, nous voulons conserver cette fonction.

Vous pouvez gérer ça manuellement ou bien avec la commande git reset HEAD .

Dans votre fichier composer, assurez-vous de changer toutes les versions 6.4.* en 7.0.*. pour les packages qui débute par symfony/

symfony composer up

Il peut arriver que tout fonctionne d’un seul coup, tout comme il peut y avoir des erreurs, dans mon cas

Quelque chose bloque la mise à jour ! La première chose que je remarque est babdev/pagerfanta-bundle. Apparemment, il fonctionne avec Symfony 4, 5 et 6, mais pas avec Symfony 7.

Il y a de fortes chances que je doive le mettre à jour vers une nouvelle version compatible avec Symfony 7. Exécutez

symfony composer outdated

Il y a trois packages pagerfanta qui ont tous une nouvelle version majeure. Dans le fichier composer.json, recherchez « pagerfanta« . Modifiez tous ces éléments pour les mettre à ^4.0 afin d’obtenir cette nouvelle version majeure.

Pour la première erreur, symfony/proxy-manager-bridge 7.0.*, ce package est directement présent dans notre fichier composer.json. Les proxys sont utilisés par Doctrine en arrière-plan pour charger les relations paresseuses. Récemment, Symfony a ajouté sa propre version des proxys appelée « ghost objects« . Ce package de proxy n’est plus nécessaire maintenant. Il a été ajouté à notre application à l’époque où nous avons installé Doctrine : il faisait auparavant partie du orm-pack.

De même vous pouvez faire la même chose, c’est à dire, dans votre fichier composer.json, assurez-vous de changer toutes les versions 7.0.* en 7.2.*. pour les packages qui débute par symfony/

symfony composer up

Il faut également vérifier les autres packages en dehors de Symfony et être particulièrement attentif lors de la mise à jour vers une version majeure.

symfony composer outdated
symfony composer why-not doctrine/dbal 4.2
....

Comme nous venons de mettre à jour certains packages, exécutez

symfony composer recipes:update

Symfony 6.3 est arrivé avec un nouveau composant appelé AssetMapper. Il nous permet d’écrire du JavaScript et du CSS modernes sans système de build.

AssetMapper est un remplacement pour Webpack Encore. Encore ne va pas disparaître de sitôt, mais on dirait qu’il commence à jeter un œil à des brochures de retraite !

Devrais-je convertir mon application de Webpack Encore à AssetMapper ?

  • La réponse est cela dépend de vous. AssetMapper est plus moderne, plus facile à utiliser, et si vous êtes frustré par les builds lents d’Encore, c’est une excellente raison de passer à AssetMapper. Mais si Encore fonctionne bien pour vous, il n’y a pas de raison de faire tout le travail pour cette conversion. De plus, si vous utilisez React ou Vue, il vaut mieux rester avec Encore, car ces frameworks nécessitent toujours une étape de build

Dans cet article nous allons migrer Encore vers AssetMapper, première chose à faire est de supprimer WebPackEncore

symfony composer remove symfony/webpack-encore-bundle

Cela supprimera ce package, sa recipe se désinstallera également. Le fichier package.json supprimé, webpack.config.js supprimé, les fonctions encore_entry_ dans base.html.twig supprimées. Mais cela a aussi supprimé app.js et app.css. Nous voulons conserver ces fichiers, donc exécutez

git checkout assets/

Dans l’ancien fichier package.json, les dépendances étaient liées à Webpack Encore et nous n’en aurons plus besoin. Cependant, certaines d’entre elles concernent notre frontend, et nous les réajouterons via AssetMapper.

Nous allons installer le package AssetMapper

symfony composer require symfony/asset-mapper

Sa recipe effectue un tas de choses intéressantes. Nous n’allons pas entrer trop en détail sur le fonctionnement d’AssetMapper. Notez juste que le fichier importmap.php. C’est, le nouveau package.json : le point central pour les packages tiers. Et regardez ! Stimulus et Turbo y sont déjà ajoutés ! Ce sont deux des packages de l’ancien package.json dont nous avons besoin.

symfony console importmap:require bootstrap

Dans votre fichier importmap.php

Ajoutez cette ligne dans votre fichier assets/app.js

import 'bootstrap/dist/css/bootstrap.min.css';

Une grande différence entre Encore et AssetMapper est que si vous devez importer un fichier spécifique depuis un package, vous devez utiliser importmap:require pour ce fichier, et non simplement pour le package en général

symfony console importmap:require @fortawesome/fontawesome-free/css/all.css

De la même façon, vous devez ajouter l’import dans votre fichier assets/app.js

import 'bootstrap/dist/css/bootstrap.min.css';
import '@fortawesome/fontawesome-free/css/all.css';

Si vous exécutez importmap:require packageName, cela récupère le fichier JavaScript du package. Dans certains cas, comme avec Bootstrap, le package indique qu’il contient un fichier CSS. Lorsque cela se produit, AssetMapper le détecte automatiquement et exécute, en pratique, importmap:require bootstrap/dist/css/bootstrap.min.css pour vous rendre service.

Avec Encore, l’importation d’un package depuis un fichier CSS entraînait automatiquement la recherche et l’importation du fichier CSS correspondant par Encore. Cependant, ce comportement diffère avec AssetMapper : vous devez identifier manuellement le chemin du fichier CSS et l’exiger explicitement.

Pour information, jsDelivr.com C’est le CDN qu’AssetMapper utilise en coulisses pour récupérer les packages.

Exemple de notre fichier assets/app.js

Avec Webpack Encore, vous travaillez dans un environnement Node. Node vous permet de ne pas spécifier l’extension .js lors de l’importation d’un fichier, car il la suppose par défaut. Cependant, dans un environnement JavaScript réel, comme votre navigateur, l’extension .js est obligatoire.

  • Autowiring Attributes
  • MapQueryParameter & Request Payload
  • Webhook et RemoteEvent Components
  • Profiling Commands
  • Component Scheduler

Le meilleur endroit pour trouver ces informations. c’est le blog de Symfony

J’espère que cela va vous aider et vous donner une vision globale sur la manière de migrer une application Symfony.