| 1 |
/** |
| 2 |
* Tailwind v3 config for building a PURGED CSS bundle for Easy Invoice. |
| 3 |
* |
| 4 |
* Why this exists: |
| 5 |
* - The shipped tailwind.min.css is 2.8 MB (full CDN dump, no purge). |
| 6 |
* - Only ~572 utility classes are actually used across all templates + |
| 7 |
* addons + admin chrome. A purged build is ~40-90 KB. |
| 8 |
* - That's a 30-90× reduction on every admin page load, which is the |
| 9 |
* single largest performance win in the perf audit. |
| 10 |
* |
| 11 |
* Behavior is opt-in. The build outputs `tailwind.purged.min.css` next to |
| 12 |
* the existing `tailwind.min.css` — the admin enqueue keeps using the |
| 13 |
* original until a future PR adds the switch. Verify visually on a few |
| 14 |
* representative pages (Dashboard, Invoice Builder, Addons grid, every |
| 15 |
* addon settings page, Settings, Reports) before enabling the swap. |
| 16 |
* |
| 17 |
* Build steps (requires Node 18+ and npm): |
| 18 |
* |
| 19 |
* cd tools/tailwind-build |
| 20 |
* npm install |
| 21 |
* npm run build |
| 22 |
* |
| 23 |
* Output: ../../assets/lib/tailwind/tailwind.purged.min.css |
| 24 |
*/ |
| 25 |
module.exports = { |
| 26 |
// The `content` array tells Tailwind which files to scan for class names. |
| 27 |
// Anything matched anywhere in these files (PHP, JS, HTML, any string |
| 28 |
// literal containing what looks like a class name) gets kept. |
| 29 |
// |
| 30 |
// Paths are relative to this config file (tools/tailwind-build/). |
| 31 |
// The pro plugin lives in a sibling dir, so we use ../../../ to reach it. |
| 32 |
content: [ |
| 33 |
'../../templates/**/*.php', |
| 34 |
'../../includes/**/*.php', |
| 35 |
'../../assets/js/**/*.js', |
| 36 |
'../../../easy-invoice-pro/includes/**/*.php', |
| 37 |
'../../../easy-invoice-pro/addons/**/*.php', |
| 38 |
'../../../easy-invoice-pro/assets/js/**/*.js', |
| 39 |
], |
| 40 |
|
| 41 |
// Safelist: classes we KNOW are used but Tailwind's scanner might miss |
| 42 |
// (dynamically composed in JS, built via string concat, etc.). The |
| 43 |
// ./safelist.txt file is generated by scanning every class= attribute |
| 44 |
// across the codebase — read it at build time. |
| 45 |
safelist: (function () { |
| 46 |
const fs = require('fs'); |
| 47 |
const path = require('path'); |
| 48 |
const file = path.join(__dirname, 'safelist.txt'); |
| 49 |
if (!fs.existsSync(file)) return []; |
| 50 |
return fs.readFileSync(file, 'utf-8') |
| 51 |
.split(/\r?\n/) |
| 52 |
.map(s => s.trim()) |
| 53 |
.filter(Boolean); |
| 54 |
})(), |
| 55 |
|
| 56 |
theme: { |
| 57 |
extend: {}, |
| 58 |
}, |
| 59 |
// No plugins by default — the codebase uses only stock utilities. |
| 60 |
// Add @tailwindcss/forms, @tailwindcss/typography etc. here if templates |
| 61 |
// start using their classes. |
| 62 |
plugins: [], |
| 63 |
}; |
| 64 |
|