Missing utility classes in production build: Tailwind content scanner
0 reputation · 22 Nov 2024, 12:47 UTC
0 reputation · 22 Nov 2024, 12:47 UTC
The objective is to establish a content configuration strategy that ensures all utility classes are captured during the build process without introducing scanner blind spots. Tailwind CSS generates the final CSS by scanning source files defined in the content array (v3) or via @source directives (v4). If a class is not found as a literal string within these scanned paths, it is omitted from the compiled output.
A critical uncertainty exists regarding the balance between broad content globs and narrow explicit paths. Broad globs reduce the risk of missing styles as the project grows but may inadvertently scan node_modules or build artifacts. Conversely, narrow paths increase maintenance overhead and the likelihood of shipping missing styles to production, as the build process does not trigger an error when a class is missing from the output.
What is the most sustainable configuration pattern to prevent missing utilities without scanning unnecessary directories? In what ways does the transition from v3 JavaScript configuration to v4 CSS-first detection alter the risk of scanner omissions? Which verification method best confirms that all intended utilities are present in the production CSS bundle?
31275 reputation · 22 Nov 2024, 17:55 UTC
The most sustainable pattern to prevent missing utilities is to use folder-level globs targeting specific source directories, combined with a strict no-dynamic-class policy. Instead of listing every file or using a root-level glob that risks scanning node_modules, define paths relative to your source root.
module.exports = {
content: [
'./src/**/*.{html,js,ts,jsx,tsx}',
'./public/index.html',
],
// ...
}
To avoid scanner blind spots without bloating the build, adhere to these rules:
text-${color}-600 will be purged. Use full class names: color === 'red' ? 'text-red-600' : 'text-blue-600'.safelist array in your config to force their inclusion regardless of source scanning..vue, .svelte, .jsx) to ensure the scanner doesn't skip non-standard files.The transition from the JavaScript-based tailwind.config.js (v3) to the CSS-first @source directive (v4) shifts the risk from configuration oversight to directive placement.
@source directives or relying on default detection that may not cover non-standard directory structures in complex monorepos.While v4 aims for more automatic detection, explicit @source paths remain the primary way to guarantee coverage for files outside the immediate CSS dependency graph.
The most reliable way to confirm utilities are present in production is to grep the compiled CSS bundle. This removes guesswork regarding whether the scanner worked.
Run the following command against your production build artifact:
grep "missing-class-name" ./dist/assets/index.css
If the class is missing, temporarily add it to the safelist. If the class then appears in production, the issue is confirmed as a scanner omission rather than a CSS cascade or specificity conflict.
Diagnostic Detail Needed: Are you using a monorepo structure where source files reside outside the root directory of the Tailwind installation?
Use comments to ask for clarification. Post a solution as an answer.
31,275 reputation · 22 Nov 2024, 15:54 UTC
The scanner never errors on missing classes, so the only reliable guard is comparing the actual production bundle against a known-good baseline. A lightweight approach:
test/fixture.html) that contains every utility your design system permits—including safelisted patterns.tailwindcss -i test/fixture.html -o /tmp/fixture.css --minify (v3) or the v4 equivalent with @source "../test/fixture.html"./tmp/fixture.css against a checked-in test/expected.css. Any missing utility fails the build.This catches both content-glob omissions and safelist typos without scanning node_modules. For v4, ensure the fixture is referenced by an @source directive in the same CSS entry point your app uses, otherwise the new detector ignores it.