mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-04 11:55:50 +00:00
150 lines
4.8 KiB
JavaScript
150 lines
4.8 KiB
JavaScript
/**
|
|
* PostCSS Configuration
|
|
*
|
|
* Processes compiled Sass output through:
|
|
* 1. PurgeCSS - Removes unused CSS selectors
|
|
* 2. Autoprefixer - Adds vendor prefixes for browser compatibility
|
|
* 3. cssnano - Minifies and optimizes CSS (production only)
|
|
*/
|
|
|
|
const purgecss = require('@fullhuman/postcss-purgecss').default;
|
|
const autoprefixer = require('autoprefixer');
|
|
const cssnano = require('cssnano');
|
|
|
|
const isProduction = process.env.NODE_ENV === 'production';
|
|
|
|
module.exports = {
|
|
plugins: [
|
|
// Only run PurgeCSS in production or when explicitly enabled
|
|
...(isProduction || process.env.PURGECSS === 'true'
|
|
? [
|
|
purgecss({
|
|
// Scan all content files for class names
|
|
content: [
|
|
'./**/*.tsx',
|
|
'./**/*.ts',
|
|
'./**/*.md',
|
|
'./**/*.yaml',
|
|
'./**/*.html',
|
|
'./static/js/**/*.js',
|
|
'./static/vendor/**/*.js',
|
|
// Ignore node_modules except for specific libraries that inject classes
|
|
'!./node_modules/**/*',
|
|
],
|
|
|
|
// Default extractor - looks for class names in content
|
|
defaultExtractor: content => {
|
|
// Match all words, including those with dashes and numbers
|
|
const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [];
|
|
// Match class names in className="..." or class="..."
|
|
const classMatches = content.match(/(?:class|className)=["']([^"']*)["']/g) || [];
|
|
const classes = classMatches.flatMap(match => {
|
|
const m = match.match(/["']([^"']*)["']/);
|
|
return m ? m[1].split(/\s+/) : [];
|
|
});
|
|
return [...broadMatches, ...classes];
|
|
},
|
|
|
|
// Safelist - classes that should never be removed
|
|
safelist: {
|
|
// Standard safelist - dynamic state classes
|
|
standard: [
|
|
'html',
|
|
'body',
|
|
'light',
|
|
'dark',
|
|
'show',
|
|
'hide',
|
|
'active',
|
|
'disabled',
|
|
'open',
|
|
'collapsed',
|
|
'collapsing',
|
|
// Common Bootstrap utility patterns that should always be kept
|
|
/^container/, // All container classes
|
|
/^row$/, // Row class
|
|
/^col-/, // Column classes
|
|
/^g-/, // Gap utilities
|
|
/^p-/, // Padding utilities
|
|
/^m-/, // Margin utilities
|
|
/^px-/, /^py-/, /^pt-/, /^pb-/, /^ps-/, /^pe-/, // Directional padding
|
|
/^mx-/, /^my-/, /^mt-/, /^mb-/, /^ms-/, /^me-/, // Directional margin
|
|
/^d-/, // Display utilities
|
|
/^flex-/, // Flexbox utilities
|
|
/^justify-/, // Justify content
|
|
/^align-/, // Align items
|
|
/^w-/, // Width utilities
|
|
/^h-/, // Height utilities
|
|
/^text-/, // Text utilities
|
|
/^bg-/, // Background utilities
|
|
/^border/, // Border utilities
|
|
/^rounded/, // Border radius
|
|
],
|
|
|
|
// Deep safelist - MINIMAL - only truly dynamic components
|
|
deep: [
|
|
// Bootstrap JS components (only if actually used with JS)
|
|
/dropdown-menu/,
|
|
/dropdown-item/,
|
|
/modal-backdrop/,
|
|
/fade/,
|
|
|
|
// Third-party libraries
|
|
/cm-/,
|
|
/CodeMirror/,
|
|
/lottie/,
|
|
],
|
|
|
|
// Greedy safelist - VERY MINIMAL
|
|
greedy: [
|
|
/data-theme/, // Theme switching
|
|
],
|
|
},
|
|
|
|
// Reject specific patterns - don't remove these even if not found
|
|
rejected: [],
|
|
|
|
// Variables - keep CSS custom properties
|
|
variables: true,
|
|
|
|
// Keyframes - keep animation keyframes
|
|
keyframes: true,
|
|
|
|
// Font-face rules
|
|
fontFace: true,
|
|
}),
|
|
]
|
|
: []),
|
|
|
|
// Autoprefixer - adds vendor prefixes
|
|
autoprefixer({
|
|
overrideBrowserslist: [
|
|
'>0.2%',
|
|
'not dead',
|
|
'not op_mini all',
|
|
'last 2 versions',
|
|
],
|
|
}),
|
|
|
|
// cssnano - minification (production only)
|
|
...(isProduction
|
|
? [
|
|
cssnano({
|
|
preset: [
|
|
'default',
|
|
{
|
|
discardComments: {
|
|
removeAll: true,
|
|
},
|
|
normalizeWhitespace: true,
|
|
colormin: true,
|
|
minifySelectors: true,
|
|
},
|
|
],
|
|
}),
|
|
]
|
|
: []),
|
|
],
|
|
};
|
|
|