applyCompatibilityHooks() — tailwindcss Function Reference
Architecture documentation for the applyCompatibilityHooks() function in apply-compat-hooks.ts from the tailwindcss codebase.
Entity Profile
Dependency Diagram
graph TD 9e2f12c0_83ef_256b_739b_9ec6ebc69b08["applyCompatibilityHooks()"] 26086ff1_0d4f_fdb2_3fc4_d0c999f90a8c["parseCss()"] 26086ff1_0d4f_fdb2_3fc4_d0c999f90a8c -->|calls| 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 aac1ce38_87b8_e2ee_838b_b9196b3e9299["cssContext()"] 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 -->|calls| aac1ce38_87b8_e2ee_838b_b9196b3e9299 af90c185_29a2_6c4c_ef06_b18f00f7655c["toCss()"] 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 -->|calls| af90c185_29a2_6c4c_ef06_b18f00f7655c 2a20ea29_c850_cd61_5600_aeebbe3dda66["segment()"] 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 -->|calls| 2a20ea29_c850_cd61_5600_aeebbe3dda66 16ea83b7_6a24_51d7_fe79_5abfdb79d93e["registerLegacyUtilities()"] 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 -->|calls| 16ea83b7_6a24_51d7_fe79_5abfdb79d93e e512528a_2506_964d_514b_bab67f99b575["resolveThemeValue()"] 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 -->|calls| e512528a_2506_964d_514b_bab67f99b575 0f8ac574_990e_8595_a6ed_11422b8a8ec4["upgradeToFullPluginSupport()"] 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 -->|calls| 0f8ac574_990e_8595_a6ed_11422b8a8ec4 e9d556bc_f22d_356c_1bd2_27442c34b5c7["walk()"] 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 -->|calls| e9d556bc_f22d_356c_1bd2_27442c34b5c7 style 9e2f12c0_83ef_256b_739b_9ec6ebc69b08 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
packages/tailwindcss/src/compat/apply-compat-hooks.ts lines 21–215
export async function applyCompatibilityHooks({
designSystem,
base,
ast,
loadModule,
sources,
}: {
designSystem: DesignSystem
base: string
ast: AstNode[]
loadModule: (
path: string,
base: string,
resourceHint: 'plugin' | 'config',
) => Promise<{
path: string
base: string
module: any
}>
sources: { base: string; pattern: string; negated: boolean }[]
}) {
let features = Features.None
let pluginPaths: [
{ id: string; base: string; reference: boolean; src: SourceLocation | undefined },
CssPluginOptions | null,
][] = []
let configPaths: {
id: string
base: string
reference: boolean
src: SourceLocation | undefined
}[] = []
walk(ast, (node, _ctx) => {
if (node.kind !== 'at-rule') return
let ctx = cssContext(_ctx)
// Collect paths from `@plugin` at-rules
if (node.name === '@plugin') {
if (ctx.parent !== null) {
throw new Error('`@plugin` cannot be nested.')
}
let pluginPath = node.params.slice(1, -1)
if (pluginPath.length === 0) {
throw new Error('`@plugin` must have a path.')
}
let options: CssPluginOptions = {}
for (let decl of node.nodes ?? []) {
if (decl.kind !== 'declaration') {
throw new Error(
`Unexpected \`@plugin\` option:\n\n${toCss([decl])}\n\n\`@plugin\` options must be a flat list of declarations.`,
)
}
if (decl.value === undefined) continue
// Parse the declaration value as a primitive type
// These are the same primitive values supported by JSON
let value: CssPluginOptions[keyof CssPluginOptions] = decl.value
let parts = segment(value, ',').map((part) => {
part = part.trim()
if (part === 'null') {
return null
} else if (part === 'true') {
return true
} else if (part === 'false') {
return false
} else if (!Number.isNaN(Number(part))) {
return Number(part)
} else if (
(part[0] === '"' && part[part.length - 1] === '"') ||
(part[0] === "'" && part[part.length - 1] === "'")
) {
return part.slice(1, -1)
} else if (part[0] === '{' && part[part.length - 1] === '}') {
throw new Error(
`Unexpected \`@plugin\` option: Value of declaration \`${toCss([decl]).trim()}\` is not supported.\n\nUsing an object as a plugin option is currently only supported in JavaScript configuration files.`,
)
}
return part
})
options[decl.property] = parts.length === 1 ? parts[0] : parts
}
pluginPaths.push([
{
id: pluginPath,
base: ctx.context.base as string,
reference: !!ctx.context.reference,
src: node.src,
},
Object.keys(options).length > 0 ? options : null,
])
features |= Features.JsPluginCompat
return WalkAction.Replace([])
}
// Collect paths from `@config` at-rules
if (node.name === '@config') {
if (node.nodes.length > 0) {
throw new Error('`@config` cannot have a body.')
}
if (ctx.parent !== null) {
throw new Error('`@config` cannot be nested.')
}
configPaths.push({
id: node.params.slice(1, -1),
base: ctx.context.base as string,
reference: !!ctx.context.reference,
src: node.src,
})
features |= Features.JsPluginCompat
return WalkAction.Replace([])
}
})
registerLegacyUtilities(designSystem)
// Override `resolveThemeValue` with a version that is backwards compatible
// with dot notation paths like `colors.red.500`. We could do this by default
// in `resolveThemeValue` but handling it here keeps all backwards
// compatibility concerns localized to our compatibility layer.
let resolveThemeVariableValue = designSystem.resolveThemeValue
designSystem.resolveThemeValue = function resolveThemeValue(path: string, forceInline?: boolean) {
if (path.startsWith('--')) {
return resolveThemeVariableValue(path, forceInline)
}
// If the theme value is not found in the simple resolver, we upgrade to the full backward
// compatibility support implementation of the `resolveThemeValue` function.
features |= upgradeToFullPluginSupport({
designSystem,
base,
ast,
sources,
configs: [],
pluginDetails: [],
})
return designSystem.resolveThemeValue(path, forceInline)
}
// If there are no plugins or configs registered, we don't need to register
// any additional backwards compatibility hooks.
if (!pluginPaths.length && !configPaths.length) return Features.None
let [configs, pluginDetails] = await Promise.all([
Promise.all(
configPaths.map(async ({ id, base, reference, src }) => {
let loaded = await loadModule(id, base, 'config')
return {
path: id,
base: loaded.base,
config: loaded.module as UserConfig,
reference,
src,
}
}),
),
Promise.all(
pluginPaths.map(async ([{ id, base, reference, src }, pluginOptions]) => {
let loaded = await loadModule(id, base, 'plugin')
return {
path: id,
base: loaded.base,
plugin: loaded.module as Plugin,
options: pluginOptions,
reference,
src,
}
}),
),
])
features |= upgradeToFullPluginSupport({
designSystem,
base,
ast,
sources,
configs,
pluginDetails,
})
return features
}
Domain
Subdomains
Calls
Called By
Source
Frequently Asked Questions
What does applyCompatibilityHooks() do?
applyCompatibilityHooks() is a function in the tailwindcss codebase.
What does applyCompatibilityHooks() call?
applyCompatibilityHooks() calls 7 function(s): cssContext, registerLegacyUtilities, resolveThemeValue, segment, toCss, upgradeToFullPluginSupport, walk.
What calls applyCompatibilityHooks()?
applyCompatibilityHooks() is called by 1 function(s): parseCss.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free