Error when @layer used without matching @tailwind directive (#4335)
Also refactor to only detect `@tailwind` directives once per build to improve performance.
This commit is contained in:
parent
87a4516871
commit
30dc2990c3
9 changed files with 145 additions and 23 deletions
|
|
@ -30,9 +30,9 @@ export default function (configOrPath = {}) {
|
|||
})
|
||||
}
|
||||
|
||||
rewriteTailwindImports(root)
|
||||
let tailwindDirectives = rewriteTailwindImports(root)
|
||||
|
||||
let context = setupContext(configOrPath)(result, root)
|
||||
let context = setupContext(configOrPath, tailwindDirectives)(result, root)
|
||||
|
||||
if (!env.TAILWIND_DISABLE_TOUCH) {
|
||||
if (context.configPath !== null) {
|
||||
|
|
@ -41,8 +41,8 @@ export default function (configOrPath = {}) {
|
|||
}
|
||||
|
||||
return postcss([
|
||||
removeLayerAtRules(context),
|
||||
expandTailwindAtRules(context, registerDependency),
|
||||
removeLayerAtRules(context, tailwindDirectives),
|
||||
expandTailwindAtRules(context, registerDependency, tailwindDirectives),
|
||||
expandApplyAtRules(context),
|
||||
evaluateTailwindFunctions(context.tailwindConfig),
|
||||
substituteScreenAtRules(context.tailwindConfig),
|
||||
|
|
|
|||
|
|
@ -111,9 +111,12 @@ function buildStylesheet(rules, context) {
|
|||
return returnValue
|
||||
}
|
||||
|
||||
export default function expandTailwindAtRules(context, registerDependency) {
|
||||
export default function expandTailwindAtRules(context, registerDependency, tailwindDirectives) {
|
||||
return (root) => {
|
||||
let foundTailwind = false
|
||||
if (tailwindDirectives.size === 0) {
|
||||
return root
|
||||
}
|
||||
|
||||
let layerNodes = {
|
||||
base: null,
|
||||
components: null,
|
||||
|
|
@ -126,8 +129,6 @@ export default function expandTailwindAtRules(context, registerDependency) {
|
|||
// file as a dependency since the output of this CSS does not depend on
|
||||
// the source of any templates. Think Vue <style> blocks for example.
|
||||
root.walkAtRules('tailwind', (rule) => {
|
||||
foundTailwind = true
|
||||
|
||||
if (rule.params === 'base') {
|
||||
layerNodes.base = rule
|
||||
}
|
||||
|
|
@ -145,10 +146,6 @@ export default function expandTailwindAtRules(context, registerDependency) {
|
|||
}
|
||||
})
|
||||
|
||||
if (!foundTailwind) {
|
||||
return root
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
if (sharedState.env.TAILWIND_DISABLE_TOUCH) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,22 @@
|
|||
export default function removeLayerAtRules() {
|
||||
export default function removeLayerAtRules(_context, tailwindDirectives) {
|
||||
return (root) => {
|
||||
root.walkAtRules((rule) => {
|
||||
if (['layer', 'responsive', 'variants'].includes(rule.name)) {
|
||||
if (rule.name === 'layer' && ['base', 'components', 'utilities'].includes(rule.params)) {
|
||||
if (!tailwindDirectives.has(rule.params)) {
|
||||
throw rule.error(
|
||||
`\`@layer ${rule.params}\` is used but no matching \`@tailwind ${rule.params}\` directive is present.`
|
||||
)
|
||||
}
|
||||
rule.remove()
|
||||
} else if (rule.name === 'responsive') {
|
||||
if (!tailwindDirectives.has('utilities')) {
|
||||
throw rule.error('`@responsive` is used but `@tailwind utilities` is missing.')
|
||||
}
|
||||
rule.remove()
|
||||
} else if (rule.name === 'variants') {
|
||||
if (!tailwindDirectives.has('utilities')) {
|
||||
throw rule.error('`@variants` is used but `@tailwind utilities` is missing.')
|
||||
}
|
||||
rule.remove()
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -23,4 +23,12 @@ export default function rewriteTailwindImports(root) {
|
|||
atRule.params = 'screens'
|
||||
}
|
||||
})
|
||||
|
||||
let tailwindDirectives = new Set()
|
||||
|
||||
root.walkAtRules('tailwind', (rule) => {
|
||||
tailwindDirectives.add(rule.params)
|
||||
})
|
||||
|
||||
return tailwindDirectives
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,6 +314,7 @@ function rebootWatcher(context) {
|
|||
touch(context.configPath)
|
||||
} else {
|
||||
context.changedFiles.add(path.resolve('.', file))
|
||||
console.log(context.touchFile)
|
||||
touch(context.touchFile)
|
||||
}
|
||||
})
|
||||
|
|
@ -686,14 +687,8 @@ function cleanupContext(context) {
|
|||
// Retrieve an existing context from cache if possible (since contexts are unique per
|
||||
// source path), or set up a new one (including setting up watchers and registering
|
||||
// plugins) then return it
|
||||
export default function setupContext(configOrPath) {
|
||||
export default function setupContext(configOrPath, tailwindDirectives) {
|
||||
return (result, root) => {
|
||||
let foundTailwind = false
|
||||
|
||||
root.walkAtRules('tailwind', () => {
|
||||
foundTailwind = true
|
||||
})
|
||||
|
||||
let sourcePath = result.opts.from
|
||||
let [
|
||||
tailwindConfig,
|
||||
|
|
@ -712,7 +707,7 @@ export default function setupContext(configOrPath) {
|
|||
// We may want to think about `@layer` being part of this trigger too, but it's tough
|
||||
// because it's impossible for a layer in one file to end up in the actual @tailwind rule
|
||||
// in another file since independent sources are effectively isolated.
|
||||
if (foundTailwind) {
|
||||
if (tailwindDirectives.size > 0) {
|
||||
contextDependencies.add(sourcePath)
|
||||
for (let message of result.messages) {
|
||||
if (message.type === 'dependency') {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue