Tailwindcss Typography Variants with PurgeCSS + Hugo

I am having trouble with purgeCSS removing variant styles that are present in the hugo_stats.js. Specifically, it appears that none of the prose styles are present in the production build

postcss.config.js:

const themeDir = __dirname + '/../../';

const purgecss = require("@fullhuman/postcss-purgecss")({
    content: ["./hugo_stats.json"],
    defaultExtractor: (content) => {
        const els = JSON.parse(content).htmlElements;
        return [...(els.tags || []), ...(els.classes || []), ...(els.ids || [])];
        // return els.tags.concat(els.classes, els.ids);
    },
    safelist: {
        deep: [/prose$/, /^dark/],
        // deep: [/^sm/, /^md/, /^lg/, /^xl/, /^2xl/, /^3xl/, /^4xl/, /^5xl/, /^6xl/, /^bg-/, /^text-/, /^prose-/, /^dark/, /2xl:prose-h1:text-6xl/],
        // greedy: [/^prose/]
    }
    // safelist: ["2xl:prose-h1:text-6xl"]
});

module.exports = {
    plugins: [
        require('tailwindcss')(themeDir + 'assets/css/tailwind.config.js'),
        require('autoprefixer')({
            path: [themeDir]
        }),
        ...process.env.HUGO_ENVIRONMENT === 'production'
            ? [purgecss]
            : []

    ]
}

head partial:

{{- $css := resources.Get "css/styles.css" | resources.PostCSS (dict "config" "./assets/css/postcss.config.js") -}} 
{{- if hugo.IsProduction }} 
    {{ $css = $css | minify | fingerprint | resources.PostProcess }} 
{{ end -}}

<link
  rel="stylesheet"
  href="{{ $css.RelPermalink }}"
  {{ if hugo.IsProduction }} 
    integrity="{{ $css.Data.Integrity }}"
  {{ end }}
  />

I have tried to use different safelist options. The /^dark/ does need to be there, but I am having no luck catching the prose and prose variants like 2xl:prose-h1:text-6xl. All of these prose classes are in the hugo_stats.js and in the class attributes of the final HTML, but the styles are not in the final CSS bundle. Everything is working as expected in development.

Does anyone have any thoughts or advice here? Thank you.

My Tailwind configuration looks similar except for the return part in defaultExtractor. I think there might be too many dots in there, why did you comment the original version out?

You might get more help by directly going into the purgecss Discussions.

By the way /prose$/ in your safelist means “all classes ending in prose”. I wonder if 2xl:prose-h1:text-6xl is better matched with /prose/ or /*prose*/. My first advise would have been to add these classes to your greedy safelist.

Thanks for the response. I have tried a few variations of safelist: { greedy: [/*prose*/, /prose/, /dark$/] }, and no luck yet.

The return statement has the same result I believe (except also adding tags). The version I have is following the PurgeCSS Hugo guide.

Thanks for the link to PurgeCSS Discussions, I will try and post there.