Tailwind CSS 如何偵測循環依賴。
在本文中,我們分析了stituteAtApply中拋出的錯誤。此錯誤與偵測到的循環依賴有關。
walk(rule.nodes, (child) => { if (child !== node) return throw new Error( `You cannot \`@apply\` the \`${candidate}\` utility here because it creates a circular dependency.`, ) })
這是圍繞此錯誤的程式碼的高級概述。
walk — 遞迴函數:
讓我們從步行開始:
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 (請給我們一顆星!)
我們也提供網頁開發和技術寫作服務。請透過hello@thinkthroo.com聯絡我們以了解更多資訊!
參考文獻:
https://github.com/tailwindlabs/tailwindcss/blob/next/packages/tailwindcss/src/ast.ts#L70
https://github.com/tailwindlabs/tailwindcss/blob/c01b8254e822d4f328674357347ca0532f1283a0/packages/tailwins/s/s>
https://stackoverflow.com/questions/71669246/need-help-using-apply-directive-in-tailwind-css-
以上是Tailwind CSS 如何偵測循環依賴。的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undress AI Tool
免費脫衣圖片

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在Node.js中發起HTTP請求有三種常用方式:使用內置模塊、axios和node-fetch。 1.使用內置的http/https模塊無需依賴,適合基礎場景,但需手動處理數據拼接和錯誤監聽,例如用https.get()獲取數據或通過.write()發送POST請求;2.axios是基於Promise的第三方庫,語法簡潔且功能強大,支持async/await、自動JSON轉換、攔截器等,推薦用於簡化異步請求操作;3.node-fetch提供類似瀏覽器fetch的風格,基於Promise且語法簡單

JavaScript的數據類型分為原始類型和引用類型。原始類型包括string、number、boolean、null、undefined和symbol,其值不可變且賦值時復制副本,因此互不影響;引用類型如對象、數組和函數存儲的是內存地址,指向同一對象的變量會相互影響。判斷類型可用typeof和instanceof,但需注意typeofnull的歷史問題。理解這兩類差異有助於編寫更穩定可靠的代碼。

JavaScript數組中,除了map和filter,還有其他強大且不常用的方法。 1.reduce不僅能求和,還可計數、分組、展平數組、構建新結構;2.find和findIndex用於查找單個元素或索引;3.some和every用於判斷是否存在或全部滿足條件;4.sort可排序但會改變原數組;5.使用時注意複製數組避免副作用。這些方法使代碼更簡潔高效。

JavaScript中filter()方法用於創建一個包含所有通過測試元素的新數組。 1.filter()不修改原數組,而是返回符合條件元素的新數組;2.基本語法為array.filter((element)=>{returncondition;});3.可按屬性值過濾對像數組,如篩選年齡大於30的用戶;4.支持多條件篩選,例如同時滿足年齡和名字長度條件;5.可處理動態條件,將篩選參數傳入函數以實現靈活過濾;6.使用時注意必須返回布爾值,避免返回空數組,以及結合其他方法實現字符串匹配等複雜邏

在JavaScript中檢查數組是否包含某個值,最常用方法是includes(),它返回布爾值,語法為array.includes(valueToFind),例如fruits.includes('banana')返回true;若需兼容舊環境,則使用indexOf(),如numbers.indexOf(20)!==-1返回true;對於對像或複雜數據,應使用some()方法進行深度比較,如users.some(user=>user.id===1)返回true。

虛擬DOM是一種優化真實DOM更新的編程概念,通過在內存中創建與真實DOM對應的樹形結構,避免頻繁直接操作真實DOM。其核心原理是:1.數據變化時生成新的虛擬DOM;2.對比新舊虛擬DOM找出最小差異;3.批量更新真實DOM以減少重排重繪開銷。此外,使用唯一穩定key可提升列表對比效率,而部分現代框架已採用其他技術替代虛擬DOM。

處理JavaScript時區問題的關鍵在於選擇合適的方法。 1.使用原生Date對象時,推薦以UTC時間進行存儲和傳輸,並在展示時轉換為用戶本地時區;2.對於復雜時區操作,可使用moment-timezone,它支持IANA時區數據庫並提供便捷的格式化與轉換功能;3.若需本地化顯示時間且不想引入第三方庫,可使用Intl.DateTimeFormat;4.推薦現代輕量方案day.js配合timezone和utc插件,其API簡潔、性能良好並支持時區轉換。

處理異步函數中的錯誤應使用try/catch、在調用鏈中處理、使用.catch()方法、並監聽unhandledrejection事件。 1.使用try/catch捕獲錯誤是推薦方式,結構清晰且能處理await中的異常;2.在調用鏈中處理錯誤可集中邏輯,適合多步驟流程;3.使用.catch()可在調用async函數後捕獲錯誤,適用於Promise組合場景;4.監聽unhandledrejection事件可記錄未處理的rejection,作為最後一道防線;以上方法共同確保異步錯誤被正確捕獲和處理。
