Repository: tailwindlabs/tailwindcss-jit (js)

Issue:
Nested @screen causing error with postcss
Hi,
I noticed an issue while using nested `@screen` in class:
```css
.secondaryLinks {
  @screen sm {
    @apply w-auto flex-grow-0;
    @apply flex gap-4;
  }
}
```
is producing :
```
./src/components/navbar/styles.module.css ((webpack)/css-loader/cjs.js??ref--5-oneOf-2-1!(webpack)/postcss-loader/cjs.js??ref--5-oneOf-2-2!./src/components/navbar/styles.module.css)
TypeError: Cannot read property 'split' of undefined
```
moving the `@screen` out of class works again.

Pull request:
Add error messages for nested at-rules & apply
This adds error messages when nesting `@apply` inside `@screen` (or any other at rule for that matter).

Closes #76 (I think)

Patch:
diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js
index 5124e21..d76274d 100644
--- a/src/lib/expandApplyAtRules.js
+++ b/src/lib/expandApplyAtRules.js
@@ -153,6 +153,22 @@ function processApply(root, context) {
 
       let [applyCandidates, important] = extractApplyCandidates(apply.params)
 
+      if (apply.parent.type === 'atrule') {
+        if (apply.parent.name === 'screen') {
+          const screenType = apply.parent.params
+
+          throw apply.error(
+            `@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${applyCandidates
+              .map((c) => `${screenType}:${c}`)
+              .join(' ')} instead.`
+          )
+        }
+
+        throw apply.error(
+          `@apply is not supported within nested at-rules like @${apply.parent.name}. You can fix this by un-nesting @${apply.parent.name}.`
+        )
+      }
+
       for (let applyCandidate of applyCandidates) {
         if (!applyClassCache.has(applyCandidate)) {
           throw apply.error(


Test patch:
diff --git a/tests/10-apply.test.js b/tests/10-apply.test.js
index d513cd1..26c08c4 100644
--- a/tests/10-apply.test.js
+++ b/tests/10-apply.test.js
@@ -4,7 +4,11 @@ const fs = require('fs')
 const path = require('path')
 
 function run(input, config = {}) {
-  return postcss([tailwind(config)]).process(input, { from: path.resolve(__filename) })
+  const { currentTestName } = expect.getState()
+
+  return postcss([tailwind(config)]).process(input, {
+    from: `${path.resolve(__filename)}?test=${currentTestName}`,
+  })
 }
 
 test('@apply', () => {
@@ -139,4 +143,76 @@ test('@apply', () => {
   })
 })
 
-// TODO: Test stuff that should throw
+test('@apply error with unknown utility', async () => {
+  let config = {
+    darkMode: 'class',
+    purge: [path.resolve(__dirname, './10-apply.test.html')],
+    corePlugins: { preflight: false },
+    plugins: [],
+  }
+
+  let css = `
+  @tailwind components;
+  @tailwind utilities;
+
+  @layer components {
+    .foo {
+      @apply a-utility-that-does-not-exist;
+    }
+  }
+`
+
+  await expect(run(css, config)).rejects.toThrowError('class does not exist')
+})
+
+test('@apply error with nested @screen', async () => {
+  let config = {
+    darkMode: 'class',
+    purge: [path.resolve(__dirname, './10-apply.test.html')],
+    corePlugins: { preflight: false },
+    plugins: [],
+  }
+
+  let css = `
+  @tailwind components;
+  @tailwind utilities;
+
+  @layer components {
+    .foo {
+      @screen md {
+        @apply text-black;
+      }
+    }
+  }
+`
+
+  await expect(run(css, config)).rejects.toThrowError(
+    '@apply is not supported within nested at-rules like @screen'
+  )
+})
+
+test('@apply error with nested @anyatrulehere', async () => {
+  let config = {
+    darkMode: 'class',
+    purge: [path.resolve(__dirname, './10-apply.test.html')],
+    corePlugins: { preflight: false },
+    plugins: [],
+  }
+
+  let css = `
+  @tailwind components;
+  @tailwind utilities;
+
+  @layer components {
+    .foo {
+      @genie {
+        @apply text-black;
+      }
+    }
+  }
+`
+
+  await expect(run(css, config)).rejects.toThrowError(
+    '@apply is not supported within nested at-rules like @genie'
+  )
+})