この記事では、substituteAtApply でスローされたエラーを分析します。このエラーは、検出された循環依存関係に関するものです。
walk(rule.nodes, (child) => { if (child !== node) return throw new Error( `You cannot \`@apply\` the \`${candidate}\` utility here because it creates a circular dependency.`, ) })
これは、このエラーに関するコードの概要です。
散歩から始めましょう:
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 は ast.ts にある再帰関数です。
node.kind === ‘context’、またはnode.kind === ‘rule’の場合、再帰的に自身を呼び出します。条件の解除はステータスに基づきます
// Stop the walk entirely if (status === WalkAction.Stop) return // Skip visiting the children of this node if (status === WalkAction.Skip) continue
次に、少しズームアウトして、apply.ts の walk 関数付近のコードを調べてみましょう
// 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.`, ) }) } } })
TailwindCSS 作成者は、必要な場合、または追加のコンテキストを提供することが合理的である場合に、コードベース全体に説明コメントを追加しました
コメント付き。
Think Throo では、オープンソース プロジェクトで使用される高度なコードベース アーキテクチャの概念を教えることを使命としています。
Next.js/React の高度なアーキテクチャ概念を実践してコーディング スキルを 10 倍にし、ベスト プラクティスを学び、実稼働レベルのプロジェクトを構築します。
私たちはオープンソースです — https://github.com/thinkthroo/thinkthroo (スターを付けてください!)
Web 開発およびテクニカル ライティング サービスも提供しています。詳細については、hello@thinkthroo.com までお問い合わせください。
https://github.com/tailwindlabs/tailwindcss/blob/next/packages/tailwindcss/src/ast.ts#L70
https://github.com/tailwindlabs/tailwindcss/blob/c01b8254e822d4f328674357347ca0532f1283a0/packages/tailwindcss/src/apply.ts
https://stackoverflow.com/questions/71669246/need-help-using-apply-directive-in-tailwind-css
https://github.com/tailwindlabs/tailwindcss/issues/2807
以上がTailwind CSS が循環依存関係を検出する方法。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。