求推荐适用于Angular的优化版Tailwind/PurgeCSS提取器
适配Angular 15的Tailwind 3自定义类提取方案
针对Tailwind默认提取逻辑误识别普通文本、组件选择器中类名的问题,这里提供一个经过测试的自定义extract函数,仅从Angular项目的class属性、所有ngClass变体、HostBindings中提取真实使用的CSS类,彻底避免冗余规则生成。
完整Tailwind配置示例
/** @type {import('tailwindcss').Config} */ module.exports = { content: { files: [ './src/**/*.{html,ts}', './projects/**/*.{html,ts}' // 有子项目时添加 ], extract: (content) => { const classes = new Set(); // 1. 提取HTML中的class属性(静态/动态绑定、插值表达式) const classAttrRegex = /class(?:="([^"]+)"|='([^']+)'|\[.*?\]="([^"]+)")/g; let match; while ((match = classAttrRegex.exec(content)) !== null) { const classStr = match[1] || match[2] || match[3]; if (!classStr) continue; // 处理插值表达式(如 {{ activeClass }}) const interpolatedVars = classStr.match(/{{\s*([\w\-\.]+)\s*}}/g); interpolatedVars?.forEach(interp => { const varName = interp.replace(/{{\s*|\s*}}/g, ''); classes.add(varName); }); // 提取直接写死的类名 classStr.split(/\s+/).forEach(cls => { if (cls && !cls.includes('{{')) classes.add(cls); }); } // 2. 提取ngClass所有变体(对象、数组、字符串、变量) const ngClassRegex = /\[ngClass\]="([^"]+)"/g; while ((match = ngClassRegex.exec(content)) !== null) { const ngClassValue = match[1]; // 对象语法:{ 'class-a': condition } const objectClasses = ngClassValue.match(/'([\w\-]+)'|\"([\w\-]+)\"/g); objectClasses?.forEach(cls => classes.add(cls.replace(/['"]/g, ''))); // 数组语法:['class-a', classVar] const arrayClasses = ngClassValue.match(/(['"])([\w\-]+)\1/g); arrayClasses?.forEach(cls => classes.add(cls.replace(/['"]/g, ''))); // 直接字符串/变量:'class-a class-b' 或 classVar const simpleClasses = ngClassValue.match(/(['"])([\w\-\s]+)\1/g); simpleClasses?.forEach(clsStr => { clsStr.replace(/['"]/g, '').split(/\s+/).forEach(cls => classes.add(cls)); }); } // 3. 提取TypeScript中的HostBindings const hostBindingRegex = /@HostBinding\(['"]class(?:\.([\w\-]+))?['"]\)/g; while ((match = hostBindingRegex.exec(content)) !== null) { // 静态绑定:@HostBinding('class.btn') if (match[1]) { classes.add(match[1]); } else { // 动态绑定:@HostBinding('class') className = 'btn btn-primary' const varMatch = content.match(/@HostBinding\(['"]class['"]\)\s+(\w+)\s*=/); if (varMatch) { const initMatch = content.match(new RegExp(`${varMatch[1]}\\s*=\\s*(['"])([\\w\\-\\s]+)\\1`)); initMatch?.[2].split(/\s+/).forEach(cls => classes.add(cls)); } } } return Array.from(classes); } }, theme: { extend: {}, }, plugins: [], }
关键逻辑说明
- class属性提取:覆盖静态class、动态绑定class、插值表达式三种场景,区分直接类名和变量引用,避免误提取插值中的变量名以外的内容。
- ngClass全场景支持:兼容Angular中ngClass的对象、数组、字符串、变量四种写法,确保所有动态生成的类名都被精准捕获。
- HostBinding处理:同时支持组件类中静态宿主类绑定和动态宿主类绑定,覆盖组件宿主元素的类名使用场景。
测试验证
可以通过以下命令生成测试CSS文件,验证是否仅保留真实使用的类:
npx tailwindcss -o test.css --content ./src/**/*.{html,ts}
内容的提问来源于stack exchange,提问作者ZolaKt
相关产品推荐
相关产品推荐

