Comment vérifier les dépendances dans les bibliothèques Sass

Jusqu'à présent, j'ai écrit sept bibliothèques Sass. La plupart d'entre elles ne sont qu'un sur-ensemble de fonctions pouvant être incluses puis utilisées dans vos projets pour vous donner plus de pouvoir sur le code..

Par exemple, SassyLists est un ensemble de fonctions permettant de manipuler les listes Sass. Ils vous aident à inverser une liste, à insérer un élément à un index spécifique, à trancher une liste entre deux index, etc..

SassyLists peut être importé en tant qu'extension Compass, mais j'ai remarqué que, parfois, les développeurs voulaient uniquement utiliser une fonction très spécifique de SassyLists afin qu'ils la copient / collent dans leur base de code. Le problème est qu'ils ne font pas toujours attention aux dépendances (par exemple, d'autres fonctions).

J'ai décidé de commencer à travailler sur un vérificateur de dépendance. L'idée est assez simple: chaque fonction avec des dépendances passera d'abord par le vérificateur de dépendances; si ce dernier trouve que certaines fonctions manquent, il avertit le développeur que la fonction ne pourra pas s'exécuter correctement.

Le construire!

Le vérificateur de dépendance est une fonction simple acceptant un nombre illimité d’arguments (noms de fonctions obligatoires).

 @function missing-dependencies ($ functions…) // Vérifier les dépendances

Avec cela, nous utilisons le fonction-existe () fonction, introduite dans Sass 3.3, qui vérifie l’existence d’une fonction donnée dans le périmètre global.

Remarque: Sass 3.3 propose également mixin-existe ()variable-existe () et variable-globale-existe ().

 @function missing-dependencies ($ functions…) @each $ function dans $ functions @if not function-existe ($ function) @return true;  @return false; 

Si pour une raison quelconque une fonction n'existe pas dans la portée, alors dépendances manquantes résultats vrai. Si toutes les fonctions sont correctes, alors il ne manque aucune dépendance, elle retournefaux.

Vous l'utiliseriez donc comme ceci:

 // @ nécessite ma-fonction // @ requiert mon-autre-fonction @function dummy () @if-dépendances manquantes (ma-fonction, mon-autre-fonction) @warn "Oups! Certaines fonctions manquent pour 'factice '! "; @retour null;  // noyau de la fonction 'factice', // ayant évidemment besoin de 'ma-fonction' et de 'ma-autre-fonction' pour fonctionner. 

Donc c'est plutôt cool.

Pousser les choses plus loin

Ce serait encore mieux si nous pouvions identifier lequel fonction est manquante, le développeur sait donc quoi faire pour résoudre le problème. Aussi, avoir à taper l'avertissement à chaque fois est un peu gênant pour pouvoir le déplacer vers le dépendances manquantes une fonction.

L'idée n'est pas si différente de ce que nous avons déjà fait. La différence est que nous allons maintenant stocker le nom des fonctions manquantes plutôt que de les renvoyer directement. Ensuite, s'il y a des fonctions manquantes, nous allons envoyer un avertissement au développeur et finalement renvoyer un booléen comme nous l'avions déjà fait..

 @function missing-dependencies ($ functions…) $ missing-dependencies: (); @each $ function dans $ functions @si not function-exist ($ function) $ missing-dependencies: append ($ missing-dependencies, $ function, virgule);  @if length ($ missing-dependencies)> 0 @warn "Dépendances non satisfaites! Les fonctions suivantes sont requises: # $ missing-dependencies.";  @return length ($ missing-dependencies)! = 0; 

Comme vous pouvez le constater, ce n’est pas beaucoup plus complexe que notre version précédente. De plus, la façon de l'utiliser est encore plus simple:

 @function dummy () @si dépendances manquantes (ma-fonction, mon-autre-fonction) @return null;  // noyau de la fonction 'factice', // ayant évidemment besoin de 'ma-fonction' et de 'ma-autre-fonction' pour fonctionner. 

Voir? Nous pouvons laisser tomber @prévenir directive, mais s'il manque une ou plusieurs fonctions, le développeur sera invité à:

Dépendances non satisfaites! Les fonctions suivantes sont requises: my-function, my-other-function.

Empêcher le vérificateur de dépendances d'être une dépendance

Le problème majeur que je peux voir avec cette fonctionnalité est que, vous avez besoin de la dépendances manquantes une fonction! À ce stade, le vérificateur de dépendance est essentiellement une dépendance… Vous voyez l'ironie.

Ceci est dû au fait dépendances manquantes (…) est traité comme une chaîne dans des situations où dépendances manquantes ne fait référence à aucune fonction, et une chaîne est toujours évaluée à vrai. Alors en faisant @if manquant-dépendances (…), vous faites effectivement @if string, ce qui est toujours vrai, donc vous finirez toujours par remplir cette condition.

Pour éviter cela, il existe un travail astucieux. Au lieu de simplement faire @if manquant-dépendances (…), nous pourrions faire @if manque-dépendances (…) == true. À sass, == est comme === dans d'autres langues, ce qui signifie qu'il vérifie non seulement la valeur mais également le type.

 @function dummy () @si dépendances manquantes (ma-fonction, mon-autre-fonction) == true @return null;  // noyau de la fonction 'factice', // ayant évidemment besoin de 'ma-fonction' et de 'ma-autre-fonction' pour fonctionner. 

Si la fonction n'existe pas, alors, comme nous l'avons vu précédemment, l'appel sera traité comme une chaîne. Pendant qu'une chaîne est évaluée à vrai, ce n'est pas strictement égal à vrai, parce que c'est un Chaîne tapez, pas un Bool type.

Donc, à ce stade, si le dépendances manquantes fonction n'existe pas, vous ne correspondez pas à la condition, donc la fonction peut s'exécuter normalement (bien que planter s'il y a une dépendance manquante quelque part dans le code). Ce qui est cool, car nous améliorons seulement les choses sans les casser.

Différents types de dépendances

Un autre problème avec cette fonctionnalité est qu'elle vérifie uniquement les fonctions manquantes, et non les mixins ou les variables globales. Cela étant dit, ceci est facilement faisable en modifiant le code du vérificateur de dépendance.

Et si chaque argument passé à la fonction pouvait être une liste de deux éléments, avec le type de dépendance comme premier argument (soit une fonctionmixin ou variable), et le nom de la dépendance en tant que deuxième? Par exemple:

dépendances manquantes (fonction my-function, variable my-cool-variable);

Si nous sommes plus susceptibles d’utiliser des fonctions comme dépendances, nous pourrions faire en sorte que une fonction Par défaut, l'appel précédent ressemblerait à ceci:

dépendances manquantes (my-function, variable my-cool-variable);

Fondamentalement, cela revient à demander à vérifier si la fonction ma fonction existe, et la variable ma-cool-variable existe, car ils sont nécessaires pour une tâche donnée. Clair jusqu'ici?

Passons maintenant au code. Nous pouvons utiliser le appel() fonction, appeler TYPE - existe (NAME). Tout le reste est le même que précédemment.

 @function missing-dependencies ($ dependencies…) $ missing-dependencies: (); @ chaque $ dépendance dans $ dépendances $ type: "fonction"; // Type de dépendance par défaut @if longueur ($ dépendance) == 2 $ type: nth ($ dépendance, 1); $ type: if (index ("fonction" "mixin" "variable", $ type), $ type, "fonction"); $ dependency: nth ($ dependency, 2);  @if not call ("# $ type -exists", $ dependency) $ missing-dependencies: append ($ missing-dependencies, $ dependency, virgule);  @if length ($ missing-dependencies)> 0 @warn "Dépendances non remplies! Les dépendances suivantes sont obligatoires: # $ missing-dependencies.";  @return $ missing-dependencies! = 0; 

Assez cool, hein? Cela rend le code légèrement plus complexe, donc à moins que vous n'ayez probablement différents types de dépendances (ce qui n'est pas mon cas avec SassyLists), je vous suggère de vous en tenir à la première version que nous avons vue.

Remarque: vous voudrez peut-être transformer automatiquement un variable tapez dans variable globale pour appeler variable-globale-existe, parce qu'il est probable qu'une variable requise est une variable globale.

Dernières pensées

C'est à peu près ça les gens. De toute évidence, ce n'est pas une fonctionnalité quotidienne de Sass. Mais je pense que dans de nombreux cas, en particulier lors de la création de bibliothèques, de frameworks et d’extensions, ce genre de conseils peut être utile. Faites-moi savoir ce que vous pensez dans les commentaires!

Ressources

  • Jouez avec cet élément essentiel sur SassMeister.