Logo Koncept47

Comment résoudre l'erreur $(…).once is not a function - Drupal 10

03/02/2023
CMS, Drupal, Javascript,

La mise à niveau vers Drupal 10 est une étape cruciale pour bénéficier des dernières fonctionnalités et améliorations de sécurité.

Cependant, cette transition peut présenter des défis, notamment l'obsolescence de core/jquery.once, une bibliothèque retirée à partir de Drupal 10.

Contexte : L'évolution de la fonctionnalité "once"

Drupal a décidé de se libérer de la dépendance à jQuery pour la fonctionnalité "once". Cette décision s'inscrit dans une volonté plus large de modernisation du framework. Ainsi, à partir de Drupal 9.3.0, core/jquery.once a été déclarée obsolète, pour être complètement retirée dans Drupal 10.

La nouvelle implémentation, réalisée en JavaScript vanilla, est maintenant disponible via la librairie core/once de Drupal.

La nouvelle API once

La librairie once offre quatre fonctions principales :

  1. once (équivalent à jQuery.fn.once)
  2. once.filter (équivalent à jQuery.fn.findOnce)
  3. once.remove (équivalent à jQuery.fn.removeOnce)
  4. once.find (nouvelle fonction sans équivalent jQuery)

Principe de base

Les fonctions once prennent généralement deux paramètres :

  • Une chaîne de caractères sans espaces (identifiant)
  • Un objet de type tableau (éléments à traiter)

La syntaxe recommandée est similaire à celle de querySelectorAll(). Notez que once ne fonctionne qu'avec des instances de Element, excluant ainsi document et window.

Pour une documentation complète, consultez la page npm de l'API once.

Fonctions détaillées

once(id, elements, context)

Sélectionne les éléments non encore "onced" et ajoute l'identifiant à l'attribut data-once.

const elements = once('myfeature', '[data-myfeature]');

once.filter(id, elements, context)

Filtre et retourne les éléments déjà "onced" avec l'identifiant spécifié.

const filteredElements = once.filter('myfeature', '[data-myfeature]');

once.remove(id, elements, context)

Supprime l'identifiant de l'attribut data-once et retourne les éléments correspondants.

const removedElements = once.remove('myfeature', '[data-myfeature]');

once.find(id, context)

Recherche dans le DOM les éléments déjà "onced" avec l'identifiant spécifié.

const oncedElements = once.find('myfeature');

Bonnes pratiques d'utilisation de once

Pour tirer le meilleur parti de la nouvelle API once, voici quelques bonnes pratiques à suivre :

  • Utilisez once de manière cohérente dans tout votre code pour éviter les comportements inattendus.
  • Choisissez des identifiants uniques et descriptifs pour vos appels once. Par exemple, utilisez 'myModule-featureName' plutôt que des noms génériques.
  • Évitez d'utiliser once de manière excessive. Réservez-le aux opérations qui doivent vraiment être exécutées une seule fois par élément.
  • Considérez l'utilisation de once.find() pour des sélections répétées d'éléments déjà traités.
  • Pensez à utiliser once.remove() lorsque vous devez réinitialiser un comportement.

// Bon exemple
once('myModule-tooltipInit', '.tooltip', context).forEach(element => {
  initTooltip(element);
});

// À éviter
once('init', '.multiple-elements', context).forEach(element => {
  // Opérations multiples et non liées
});

Impact sur les performances

Le passage de jQuery.once à l'API native once apporte des améliorations notables en termes de performances :

  • Réduction de la taille du code : L'élimination de la dépendance à jQuery pour cette fonctionnalité réduit la quantité de JavaScript à charger.
  • Exécution plus rapide : L'implémentation en JavaScript vanilla est généralement plus rapide que son équivalent jQuery.
  • Moins de surcharge : L'utilisation d'une API plus légère et ciblée réduit la surcharge globale du traitement JavaScript.

Ces améliorations contribuent à des temps de chargement plus rapides et une meilleure réactivité des sites Drupal, particulièrement bénéfiques pour les utilisateurs sur des appareils ou connexions moins performants.

Résolution de l'erreur "$(…).once is not a function"

Si vous rencontrez cette erreur lors de la mise à niveau vers Drupal 10, suivez ces étapes :

Modification du fichier libraries.yml

Remplacez core/jquery.once par core/once dans les dépendances :

dependencies:
  - core/jquery
  - core/once

Modification des fichiers JavaScript

Modifiez vos appels à la fonction once dans vos thèmes et modules personnalisés :

Avant :

const $timezone = $(context).find('.timezone-detect').once('timezone');

Après :

const $timezone = $(once('timezone', '.timezone-detect', context));

Solutions alternatives

Pour les sites très volumineux ou anciens où la modification de tous les fichiers JavaScript serait trop complexe, il existe une solution temporaire :

Le module jQuery Once peut être utilisé pour rétablir la fonctionnalité jQuery.once dans Drupal 10.

composer require 'drupal/jquery_once:^1.0'

Après l'installation, assurez-vous d'inclure la dépendance dans vos fichiers *.libraries.yml :

dependencies:
  - jquery_once/jquery.once

Cependant, il est important de noter que cette approche n'est pas recommandée à long terme et devrait être considérée uniquement comme une mesure transitoire.

Bien que cet article se concentre sur la résolution de l'erreur liée à once, la mise à niveau vers Drupal 10 peut présenter de nombreux autres défis. Une approche méthodique et une compréhension approfondie des changements apportés à chaque version sont essentielles pour une transition réussie.

Dans la même catégorie

Vous avez un projet internet? Parlons en aujourd'hui

Contactez-nous!
Copyright ©2024 Koncept47
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram