substituteAtApply() — tailwindcss Function Reference
Architecture documentation for the substituteAtApply() function in apply.ts from the tailwindcss codebase.
Entity Profile
Dependency Diagram
graph TD 96876152_5423_5f9b_9f88_1db666070351["substituteAtApply()"] ca8635ee_31ba_d4fd_68e2_ee9e03168422["apply.ts"] 96876152_5423_5f9b_9f88_1db666070351 -->|defined in| ca8635ee_31ba_d4fd_68e2_ee9e03168422 3f0c9850_42a7_e7cb_36cc_12b1cb9274dd["createUtilitySignatureCache()"] 3f0c9850_42a7_e7cb_36cc_12b1cb9274dd -->|calls| 96876152_5423_5f9b_9f88_1db666070351 5db4b61f_a5d4_16b1_b2ec_707bde46324a["createVariantSignatureCache()"] 5db4b61f_a5d4_16b1_b2ec_707bde46324a -->|calls| 96876152_5423_5f9b_9f88_1db666070351 2efa0a66_c375_c031_24ad_1f7509bb9b14["buildPluginApi()"] 2efa0a66_c375_c031_24ad_1f7509bb9b14 -->|calls| 96876152_5423_5f9b_9f88_1db666070351 3970218d_3d6c_e455_87cc_45b4a094f0e9["parseCss()"] 3970218d_3d6c_e455_87cc_45b4a094f0e9 -->|calls| 96876152_5423_5f9b_9f88_1db666070351 66319c06_7c38_f9ea_4bf0_2a0e18bac1a4["rule()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| 66319c06_7c38_f9ea_4bf0_2a0e18bac1a4 ed78da58_8727_ad98_120c_61f35cea357a["walk()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| ed78da58_8727_ad98_120c_61f35cea357a 5bcf4886_1230_a8ff_7302_a26cc5a9a525["get()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| 5bcf4886_1230_a8ff_7302_a26cc5a9a525 62436583_15a6_57bd_b409_5a273dcefbf6["resolveApplyDependencies()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| 62436583_15a6_57bd_b409_5a273dcefbf6 2da63033_d079_7b37_5cfb_3877674a70b9["toCss()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| 2da63033_d079_7b37_5cfb_3877674a70b9 f611bd99_74d3_1161_f7f5_4c1d73c377e5["compileCandidates()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| f611bd99_74d3_1161_f7f5_4c1d73c377e5 f712ed47_45d4_4e5a_dd73_fdefa1da71da["segment()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| f712ed47_45d4_4e5a_dd73_fdefa1da71da 88bcab2f_f837_9e57_5b6a_fda72a4c3315["cloneAstNode()"] 96876152_5423_5f9b_9f88_1db666070351 -->|calls| 88bcab2f_f837_9e57_5b6a_fda72a4c3315 style 96876152_5423_5f9b_9f88_1db666070351 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
packages/tailwindcss/src/apply.ts lines 10–300
export function substituteAtApply(ast: AstNode[], designSystem: DesignSystem) {
let features = Features.None
// Wrap the whole AST in a root rule to make sure there is always a parent
// available for `@apply` at-rules. In some cases, the incoming `ast` just
// contains `@apply` at-rules which means that there is no proper parent to
// rely on.
let root = rule('&', ast)
// Track all nodes containing `@apply`
let parents = new Set<AstNode>()
// Track all the dependencies of an `AstNode`
let dependencies = new DefaultMap<AstNode, Set<string>>(() => new Set<string>())
// Track all `@utility` definitions by its root (name)
let definitions = new DefaultMap(() => new Set<AstNode>())
// Collect all new `@utility` definitions and all `@apply` rules first
walk([root], (node, ctx) => {
if (node.kind !== 'at-rule') return
// Do not allow `@apply` rules inside `@keyframes` rules.
if (node.name === '@keyframes') {
walk(node.nodes, (child) => {
if (child.kind === 'at-rule' && child.name === '@apply') {
throw new Error(`You cannot use \`@apply\` inside \`@keyframes\`.`)
}
})
return WalkAction.Skip
}
// `@utility` defines a utility, which is important information in order to
// do a correct topological sort later on.
if (node.name === '@utility') {
let name = node.params.replace(/-\*$/, '')
definitions.get(name).add(node)
// In case `@apply` rules are used inside `@utility` rules.
walk(node.nodes, (child) => {
if (child.kind !== 'at-rule' || child.name !== '@apply') return
parents.add(node)
for (let dependency of resolveApplyDependencies(child, designSystem)) {
dependencies.get(node).add(dependency)
}
})
return
}
// Any other `@apply` node.
if (node.name === '@apply') {
// `@apply` cannot be top-level, so we need to have a parent such that we
// can replace the `@apply` node with the actual utility classes later.
if (ctx.parent === null) return
features |= Features.AtApply
parents.add(ctx.parent)
for (let dependency of resolveApplyDependencies(node, designSystem)) {
// Mark every parent in the path as having a dependency to that utility.
for (let parent of ctx.path()) {
if (!parents.has(parent)) continue
dependencies.get(parent).add(dependency)
}
}
}
})
// Topological sort before substituting `@apply`
let seen = new Set<AstNode>()
let sorted: AstNode[] = []
let wip = new Set<AstNode>()
function visit(node: AstNode, path: AstNode[] = []) {
if (seen.has(node)) {
return
}
Domain
Subdomains
Defined In
Source
Frequently Asked Questions
What does substituteAtApply() do?
substituteAtApply() is a function in the tailwindcss codebase, defined in packages/tailwindcss/src/apply.ts.
Where is substituteAtApply() defined?
substituteAtApply() is defined in packages/tailwindcss/src/apply.ts at line 10.
What does substituteAtApply() call?
substituteAtApply() calls 8 function(s): cloneAstNode, compileCandidates, get, resolveApplyDependencies, rule, segment, toCss, walk.
What calls substituteAtApply()?
substituteAtApply() is called by 4 function(s): buildPluginApi, createUtilitySignatureCache, createVariantSignatureCache, parseCss.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free