Maison  >  Article  >  interface Web  >  Comment Tailwind CSS détecte la dépendance circulaire.

Comment Tailwind CSS détecte la dépendance circulaire.

Patricia Arquette
Patricia Arquetteoriginal
2024-10-09 06:19:02625parcourir

How Tailwind CSS detects circular dependancy.

Dans cet article, nous analysons l'erreur générée dans substitutAtApply. Cette erreur concerne la dépendance circulaire détectée.

walk(rule.nodes, (child) => {
  if (child !== node) return
  throw new Error(
   `You cannot \`@apply\` the \`${candidate}\` utility here because it creates a circular dependency.`,
   )
})

Ceci est un aperçu de haut niveau du code autour de cette erreur.

marcher — fonction récursive :

Commençons par la marche :

export function walk(
   ast: AstNode[],
   visit: (
     node: AstNode,
     utils: {
     parent: AstNode | null
     replaceWith(newNode: AstNode | AstNode[]): void
     context: Record<string, string>
   },
 ) => void | WalkAction,
 parent: AstNode | null = null,
 context: Record<string, string> = {},
) {
 for (let i = 0; i < ast.length; i++) {
   let node = ast[i]
  // We want context nodes to be transparent in walks. This means that
   // whenever we encounter one, we immediately walk through its children and
   // furthermore we also don't update the parent.
 if (node.kind === 'context') {
   walk(node.nodes, visit, parent, { …context, …node.context })
   continue
 }
let status = visit(node, {
   parent,
   replaceWith(newNode) {
   ast.splice(i, 1, …(Array.isArray(newNode) ? newNode : [newNode]))
   // We want to visit the newly replaced node(s), which start at the
   // current index (i). By decrementing the index here, the next loop
   // will process this position (containing the replaced node) again.
   i - 
 },
 context,
 }) ?? WalkAction.Continue
  // Stop the walk entirely
   if (status === WalkAction.Stop) return
  // Skip visiting the children of this node
   if (status === WalkAction.Skip) continue
  if (node.kind === 'rule') {
   walk(node.nodes, visit, node, context)
   }
 }
}

walk est une fonction récursive située dans ast.ts.

Il s'appelle récursivement lorsque node.kind === 'context' ou lorsque node.kind === 'rule', la condition de rupture est basée sur le statut

// Stop the walk entirely
if (status === WalkAction.Stop) return
// Skip visiting the children of this node
if (status === WalkAction.Skip) continue

Maintenant, faisons un zoom arrière et étudions le code à proximité de la fonction walk dans apply.ts

// Verify that we don't have any circular dependencies by verifying that
// the current node does not appear in the new nodes.
walk(newNodes, (child) => {
 if (child !== node) return
  // At this point we already know that we have a circular dependency.
  //
  // Figure out which candidate caused the circular dependency. This will
 // help to create a useful error message for the end user.
 for (let candidate of candidates) {
   let selector = `.${escape(candidate)}`
    for (let rule of candidateAst) {
     if (rule.kind !== 'rule') continue
     if (rule.selector !== selector) continue
      walk(rule.nodes, (child) => {
     if (child !== node) return
      throw new Error(
       `You cannot \`@apply\` the \`${candidate}\` utility here because it creates a circular dependency.`,
       )
     })
    }
 }
})

Les auteurs de TailwindCSS ont ajouté des commentaires explicatifs dans la base de code lorsque cela est nécessaire ou il est logique de fournir un contexte supplémentaire

avec commentaires.

À propos de nous :

Chez Think Throo, nous avons pour mission d'enseigner les concepts architecturaux avancés de base de code utilisés dans les projets open source.

10x vos compétences en codage en pratiquant des concepts architecturaux avancés dans Next.js/React, apprenez les meilleures pratiques et construisez des projets de niveau production.

Nous sommes open source — https://github.com/thinkthroo/thinkthroo (Donnez-nous une étoile !)

Nous fournissons également des services de développement Web et de rédaction technique. Contactez-nous à hello@thinkthroo.com pour en savoir plus !

Références :

  1. https://github.com/tailwindlabs/tailwindcss/blob/next/packages/tailwindcss/src/ast.ts#L70

  2. https://github.com/tailwindlabs/tailwindcss/blob/c01b8254e822d4f328674357347ca0532f1283a0/packages/tailwindcss/src/apply.ts

  3. https://stackoverflow.com/questions/71669246/need-help-using-apply-directive-in-tailwind-css

  4. https://github.com/tailwindlabs/tailwindcss/issues/2807

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn