Repository: tailwindlabs/tailwindcss-jit (js)

Issue:
Arbitrary values with commas don't work in production builds in Next.js
Hey! First and foremost, thank you for Tailwind and all the content surrounding it. It's amazing and your work is greatly appreciated. And `@tailwindcss/jit` is just... wow. 😍 

---

I took JIT for a spin and noticed at least one class family (`grid-cols-`) is not working in production builds, even though it works in development mode.

For example:

```jsx
function Home() {
  return (
    <div className="px-96">
      <main className="grid grid-cols-[1fr,128px] gap-x-4 items-center p-8">
        <div className="bg-blue-400">Big column</div>
        <div className="bg-gray-400">Small column</div>
      </main>
    </div>
  )
}

export default Home;
```

Development:

```css
.grid-cols-\[1fr\,128px\] {
    grid-template-columns: 1fr 128px;
}
```

![dev](https://user-images.githubusercontent.com/1288694/111255448-ae63af80-85dc-11eb-931e-102e25e0f37f.png)

Production:

(no rules applied for `grid-cols-[1fr,128px]` class)

![prod](https://user-images.githubusercontent.com/1288694/111255461-b3c0fa00-85dc-11eb-91c8-691fe3c4a8e6.png)

Full reproduction with Next.js: https://github.com/wKovacs64/tw-jit-next/tree/issue-45

Any thoughts? Thanks!


Pull request description:
Re-escape commas when updating classes
Fixes #45

When running classes through `postcss-selector-parser` (in `updateAllClasses` and `updateLastClasses`) the classes (which we have already escaped, see #91) are re-escaped, and the commas are converted back from `\2c `&nbsp;to `\,`. This PR converts them back so that commas in classes containing variants are not affected by the minifier bug.

I'm not sure if setting `raws.value` is the best way to do this, so open to other suggestions! Another option I considered is to run `escapeCommas` on the `result` in these functions, but `result` is a _full_ selector (e.g. `.something .another div`) so this felt less "correct" to me.

Patch:
diff --git a/src/lib/utils.js b/src/lib/utils.js
index 10dfe93..0d07913 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -89,5 +89,6 @@ module.exports = {
   bigSign,
   isPlainObject,
   escapeClassName,
+  escapeCommas,
   nameClass,
 }
diff --git a/src/pluginUtils.js b/src/pluginUtils.js
index 417e9d6..4ddc46f 100644
--- a/src/pluginUtils.js
+++ b/src/pluginUtils.js
@@ -1,7 +1,7 @@
 const selectorParser = require('postcss-selector-parser')
 const postcss = require('postcss')
 const { toRgba } = require('tailwindcss/lib/util/withAlphaVariable')
-const { nameClass } = require('./lib/utils')
+const { nameClass, escapeCommas } = require('./lib/utils')
 
 function updateAllClasses(selectors, updateClass) {
   let parser = selectorParser((selectors) => {
@@ -13,6 +13,9 @@ function updateAllClasses(selectors, updateClass) {
         },
       })
       sel.value = updatedClass
+      if (sel.raws && sel.raws.value) {
+        sel.raws.value = escapeCommas(sel.raws.value)
+      }
     })
   })
 
@@ -37,6 +40,9 @@ function updateLastClasses(selectors, updateClass) {
         },
       })
       lastClass.value = updatedClass
+      if (lastClass.raws && lastClass.raws.value) {
+        lastClass.raws.value = escapeCommas(lastClass.raws.value)
+      }
     })
   })
   let result = parser.processSync(selectors)


Test patch:
diff --git a/tests/08-arbitrary-values.test.css b/tests/08-arbitrary-values.test.css
index 29f73b4..1906465 100644
--- a/tests/08-arbitrary-values.test.css
+++ b/tests/08-arbitrary-values.test.css
@@ -79,3 +79,8 @@
 .duration-\[2s\] {
   transition-duration: 2s;
 }
+@media (min-width: 1024px) {
+  .lg\:grid-cols-\[200px\2c repeat\(auto-fill\2c minmax\(15\%\2c 100px\)\)\2c 300px\] {
+    grid-template-columns: 200px repeat(auto-fill, minmax(15%, 100px)) 300px;
+  }
+}
diff --git a/tests/08-arbitrary-values.test.html b/tests/08-arbitrary-values.test.html
index f414c70..3f39b53 100644
--- a/tests/08-arbitrary-values.test.html
+++ b/tests/08-arbitrary-values.test.html
@@ -19,6 +19,7 @@
     <div class="space-x-[20cm]"></div>
     <div class="space-x-[calc(20%-1cm)]"></div>
     <div class="grid-cols-[200px,repeat(auto-fill,minmax(15%,100px)),300px]"></div>
+    <div class="lg:grid-cols-[200px,repeat(auto-fill,minmax(15%,100px)),300px]"></div>
     <div class="rotate-[23deg] rotate-[2.3rad] rotate-[401grad] rotate-[1.5turn]"></div>
     <div class="text-[2.23rem]"></div>
     <div class="duration-[2s]"></div>