diff --git a/__tests__/fixtures/purge-example.html b/__tests__/fixtures/purge-example.html index 0a4a8e96fbf8..c025787719b5 100644 --- a/__tests__/fixtures/purge-example.html +++ b/__tests__/fixtures/purge-example.html @@ -1,5 +1,14 @@ -
+ + + My Page + + +
+
+
+ + @@ -19,4 +28,10 @@ .col-span-2 Hello .col-span-1.text-center - World! \ No newline at end of file + World! + + +.flow-root + .text-green-700.bg-green-100 + .text-left= content + %samp= output \ No newline at end of file diff --git a/__tests__/purgeUnusedStyles.test.js b/__tests__/purgeUnusedStyles.test.js index cc7f5c485e6f..6d6a7eb17d49 100644 --- a/__tests__/purgeUnusedStyles.test.js +++ b/__tests__/purgeUnusedStyles.test.js @@ -25,6 +25,37 @@ const config = { }, } +function assertPurged(result) { + expect(result.css).not.toContain('.bg-red-600') + expect(result.css).not.toContain('.w-1\\/3') + expect(result.css).not.toContain('.flex') + expect(result.css).not.toContain('.font-sans') + expect(result.css).not.toContain('.text-right') + expect(result.css).not.toContain('.px-4') + expect(result.css).not.toContain('.h-full') + + expect(result.css).toContain('.bg-red-500') + expect(result.css).toContain('.md\\:bg-blue-300') + expect(result.css).toContain('.w-1\\/2') + expect(result.css).toContain('.block') + expect(result.css).toContain('.md\\:flow-root') + expect(result.css).toContain('.h-screen') + expect(result.css).toContain('.min-h-\\(screen-4\\)') + expect(result.css).toContain('.bg-black\\!') + expect(result.css).toContain('.font-\\%\\#\\$\\@') + expect(result.css).toContain('.w-\\(1\\/2\\+8\\)') + expect(result.css).toContain('.inline-grid') + expect(result.css).toContain('.grid-cols-3') + expect(result.css).toContain('.px-1\\.5') + expect(result.css).toContain('.col-span-2') + expect(result.css).toContain('.col-span-1') + expect(result.css).toContain('.text-center') + expect(result.css).toContain('.flow-root') + expect(result.css).toContain('.text-green-700') + expect(result.css).toContain('.bg-green-100') + expect(result.css).toContain('.text-left') +} + test('purges unused classes', () => { const OLD_NODE_ENV = process.env.NODE_ENV process.env.NODE_ENV = 'production' @@ -41,30 +72,7 @@ test('purges unused classes', () => { .then(result => { process.env.NODE_ENV = OLD_NODE_ENV - expect(result.css).not.toContain('.bg-red-600') - expect(result.css).not.toContain('.w-1\\/3') - expect(result.css).not.toContain('.flex') - expect(result.css).not.toContain('.font-sans') - expect(result.css).not.toContain('.text-right') - expect(result.css).not.toContain('.px-4') - expect(result.css).not.toContain('.h-full') - - expect(result.css).toContain('.bg-red-500') - expect(result.css).toContain('.md\\:bg-blue-300') - expect(result.css).toContain('.w-1\\/2') - expect(result.css).toContain('.block') - expect(result.css).toContain('.md\\:flow-root') - expect(result.css).toContain('.h-screen') - expect(result.css).toContain('.min-h-\\(screen-4\\)') - expect(result.css).toContain('.bg-black\\!') - expect(result.css).toContain('.font-\\%\\#\\$\\@') - expect(result.css).toContain('.w-\\(1\\/2\\+8\\)') - expect(result.css).toContain('.inline-grid') - expect(result.css).toContain('.grid-cols-3') - expect(result.css).toContain('.px-1\\.5') - expect(result.css).toContain('.col-span-2') - expect(result.css).toContain('.col-span-1') - expect(result.css).toContain('.text-center') + assertPurged(result) }) }) @@ -85,31 +93,7 @@ test('does not purge components', () => { process.env.NODE_ENV = OLD_NODE_ENV expect(result.css).toContain('.container') - - expect(result.css).not.toContain('.bg-red-600') - expect(result.css).not.toContain('.w-1\\/3') - expect(result.css).not.toContain('.flex') - expect(result.css).not.toContain('.font-sans') - expect(result.css).not.toContain('.text-right') - expect(result.css).not.toContain('.px-4') - expect(result.css).not.toContain('.h-full') - - expect(result.css).toContain('.bg-red-500') - expect(result.css).toContain('.md\\:bg-blue-300') - expect(result.css).toContain('.w-1\\/2') - expect(result.css).toContain('.block') - expect(result.css).toContain('.md\\:flow-root') - expect(result.css).toContain('.h-screen') - expect(result.css).toContain('.min-h-\\(screen-4\\)') - expect(result.css).toContain('.bg-black\\!') - expect(result.css).toContain('.font-\\%\\#\\$\\@') - expect(result.css).toContain('.w-\\(1\\/2\\+8\\)') - expect(result.css).toContain('.inline-grid') - expect(result.css).toContain('.grid-cols-3') - expect(result.css).toContain('.px-1\\.5') - expect(result.css).toContain('.col-span-2') - expect(result.css).toContain('.col-span-1') - expect(result.css).toContain('.text-center') + assertPurged(result) }) }) @@ -177,30 +161,7 @@ test('purges outside of production if explicitly enabled', () => { .then(result => { process.env.NODE_ENV = OLD_NODE_ENV - expect(result.css).not.toContain('.bg-red-600') - expect(result.css).not.toContain('.w-1\\/3') - expect(result.css).not.toContain('.flex') - expect(result.css).not.toContain('.font-sans') - expect(result.css).not.toContain('.text-right') - expect(result.css).not.toContain('.px-4') - expect(result.css).not.toContain('.h-full') - - expect(result.css).toContain('.bg-red-500') - expect(result.css).toContain('.md\\:bg-blue-300') - expect(result.css).toContain('.w-1\\/2') - expect(result.css).toContain('.block') - expect(result.css).toContain('.md\\:flow-root') - expect(result.css).toContain('.h-screen') - expect(result.css).toContain('.min-h-\\(screen-4\\)') - expect(result.css).toContain('.bg-black\\!') - expect(result.css).toContain('.font-\\%\\#\\$\\@') - expect(result.css).toContain('.w-\\(1\\/2\\+8\\)') - expect(result.css).toContain('.inline-grid') - expect(result.css).toContain('.grid-cols-3') - expect(result.css).toContain('.px-1\\.5') - expect(result.css).toContain('.col-span-2') - expect(result.css).toContain('.col-span-1') - expect(result.css).toContain('.text-center') + assertPurged(result) }) }) @@ -222,31 +183,8 @@ test('purgecss options can be provided', () => { ]) .process(input, { from: inputPath }) .then(result => { - expect(result.css).not.toContain('.bg-red-600') - expect(result.css).not.toContain('.w-1\\/3') - expect(result.css).not.toContain('.flex') - expect(result.css).not.toContain('.font-sans') - expect(result.css).not.toContain('.text-right') - expect(result.css).not.toContain('.px-4') - expect(result.css).not.toContain('.h-full') - expect(result.css).toContain('.md\\:bg-green-500') - expect(result.css).toContain('.bg-red-500') - expect(result.css).toContain('.md\\:bg-blue-300') - expect(result.css).toContain('.w-1\\/2') - expect(result.css).toContain('.block') - expect(result.css).toContain('.md\\:flow-root') - expect(result.css).toContain('.h-screen') - expect(result.css).toContain('.min-h-\\(screen-4\\)') - expect(result.css).toContain('.bg-black\\!') - expect(result.css).toContain('.font-\\%\\#\\$\\@') - expect(result.css).toContain('.w-\\(1\\/2\\+8\\)') - expect(result.css).toContain('.inline-grid') - expect(result.css).toContain('.grid-cols-3') - expect(result.css).toContain('.px-1\\.5') - expect(result.css).toContain('.col-span-2') - expect(result.css).toContain('.col-span-1') - expect(result.css).toContain('.text-center') + assertPurged(result) }) }) @@ -271,28 +209,14 @@ test('can purge all CSS, not just Tailwind classes', () => { ]) .process(input, { from: inputPath }) .then(result => { - expect(result.css).not.toContain('html') - expect(result.css).not.toContain('body') + expect(result.css).toContain('html') + expect(result.css).toContain('body') + expect(result.css).toContain('samp') expect(result.css).not.toContain('button') expect(result.css).not.toContain('legend') expect(result.css).not.toContain('progress') - expect(result.css).toContain('.bg-red-500') - expect(result.css).toContain('.md\\:bg-blue-300') - expect(result.css).toContain('.w-1\\/2') - expect(result.css).toContain('.block') - expect(result.css).toContain('.md\\:flow-root') - expect(result.css).toContain('.h-screen') - expect(result.css).toContain('.min-h-\\(screen-4\\)') - expect(result.css).toContain('.bg-black\\!') - expect(result.css).toContain('.font-\\%\\#\\$\\@') - expect(result.css).toContain('.w-\\(1\\/2\\+8\\)') - expect(result.css).toContain('.inline-grid') - expect(result.css).toContain('.grid-cols-3') - expect(result.css).toContain('.px-1\\.5') - expect(result.css).toContain('.col-span-2') - expect(result.css).toContain('.col-span-1') - expect(result.css).toContain('.text-center') + assertPurged(result) }) }) diff --git a/src/lib/purgeUnusedStyles.js b/src/lib/purgeUnusedStyles.js index 23beefcf462e..48ba6a85f41a 100644 --- a/src/lib/purgeUnusedStyles.js +++ b/src/lib/purgeUnusedStyles.js @@ -67,7 +67,7 @@ export default function purgeUnusedUtilities(config) { const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [] // Capture classes within other delimiters like .block(class="w-1/2") in Pug - const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || [] + const innerMatches = content.match(/[^<>"'`\s.()=%]*[^<>"'`\s.()=%:]/g) || [] return broadMatches.concat(innerMatches) },