From 8f2aa3a2b7cd72ccb4efa1a89397f343638d1adb Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Wed, 7 Aug 2024 15:50:25 +0200 Subject: [PATCH] Error on invalid @plugin usage (#14134) This PR just adds two minor errors to guard against invalid `@plugin` usage similarly to what we do with `@source` in https://github.com/tailwindlabs/tailwindcss/pull/14078. --- packages/tailwindcss/src/index.test.ts | 38 ++++++++++++++++++++++++++ packages/tailwindcss/src/index.ts | 10 ++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 9e1a5a8dd..70d239deb 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -1258,6 +1258,44 @@ describe('Parsing themes values from CSS', () => { }) describe('plugins', () => { + test('@plugin can not have a body.', () => { + expect(() => + compile( + css` + @plugin { + color: red; + } + `, + { + loadPlugin: () => { + return ({ addVariant }) => { + addVariant('hocus', '&:hover, &:focus') + } + }, + }, + ).build(['hocus:underline']), + ).toThrowErrorMatchingInlineSnapshot(`[Error: \`@plugin\` cannot have a body.]`) + }) + + test('@plugin cannot be nested.', () => { + expect(() => + compile( + css` + div { + @plugin "my-plugin"; + } + `, + { + loadPlugin: () => { + return ({ addVariant }) => { + addVariant('hocus', '&:hover, &:focus') + } + }, + }, + ).build(['hocus:underline']), + ).toThrowErrorMatchingInlineSnapshot(`[Error: \`@plugin\` cannot be nested.]`) + }) + test('addVariant with string selector', () => { let compiled = compile( css` diff --git a/packages/tailwindcss/src/index.ts b/packages/tailwindcss/src/index.ts index 73b040d4e..8b61e65b2 100644 --- a/packages/tailwindcss/src/index.ts +++ b/packages/tailwindcss/src/index.ts @@ -78,7 +78,15 @@ export function compile( if (node.kind !== 'rule') return // Collect paths from `@plugin` at-rules - if (node.selector.startsWith('@plugin ')) { + if (node.selector === '@plugin' || node.selector.startsWith('@plugin ')) { + if (node.nodes.length > 0) { + throw new Error('`@plugin` cannot have a body.') + } + + if (parent !== null) { + throw new Error('`@plugin` cannot be nested.') + } + plugins.push(loadPlugin(node.selector.slice(9, -1))) replaceWith([]) return