tubalmartin/cssmin
PHP CSS minifier ported from YUI Compressor (v2.4.8) with extra fixes/features. Compress CSS via PHP API, CLI, or GUI; options include keeping sourcemap comments, removing important comments, and line break control. Composer install; PHP 5.3.2+.
Install via Composer:
composer require tubalmartin/cssmin
First Use Case: Minify a single CSS file in a Laravel controller or service:
use tubalmartin\CssMin\Minifier as CSSmin;
// Load CSS
$css = file_get_contents(public_path('css/styles.css'));
// Minify
$minifier = new CSSmin();
$minified = $minifier->run($css);
// Save to disk
file_put_contents(public_path('css/styles.min.css'), $minified);
Key Files to Review:
vendor/tubalmartin/cssmin/src/Minifier.php (Core class)vendor/bin/cssmin (CLI tool)Integrate with Laravel's asset pipeline (e.g., app/Providers/AppServiceProvider.php):
use tubalmartin\CssMin\Minifier;
public function boot()
{
$minifier = new Minifier();
// Minify all CSS files in public/css
foreach (glob(public_path('css/*.css')) as $file) {
$css = file_get_contents($file);
$minified = $minifier->run($css);
file_put_contents($file, $minified);
}
}
Create middleware to minify CSS on-the-fly:
use tubalmartin\CssMin\Minifier;
class MinifyCssMiddleware
{
protected $minifier;
public function __construct()
{
$this->minifier = new Minifier();
}
public function handle($request, Closure $next)
{
if ($request->is('css/*')) {
$path = $request->path();
$css = file_get_contents(public_path("css/{$path}"));
$minified = $this->minifier->run($css);
return response($minified, 200, ['Content-Type' => 'text/css']);
}
return $next($request);
}
}
Use the CLI tool in artisan commands:
// In a custom Artisan command
$output = Artisan::call('vendor/bin/cssmin', [
'-i' => public_path('css/styles.css'),
'-o' => public_path('css/styles.min.css'),
'--keep-sourcemap' => true,
]);
Centralize minification settings in config/cssmin.php:
return [
'keep_sourcemap' => env('CSSMIN_KEEP_SOURCEMAP', false),
'remove_important_comments' => env('CSSMIN_REMOVE_IMPORTANT', true),
'linebreak_position' => env('CSSMIN_LINEBREAK', 1000),
'memory_limit' => env('CSSMIN_MEMORY', '256M'),
];
Then load in a service:
$minifier = new Minifier();
$minifier->keepSourceMapComment(config('cssmin.keep_sourcemap'));
$minifier->setLineBreakPosition(config('cssmin.linebreak_position'));
Trigger minification via Laravel events (e.g., assets:updated):
// In EventServiceProvider
protected $listen = [
'assets.updated' => [
'App\Listeners\MinifyCssAssets',
],
];
PHP Limits:
memory_limit, max_execution_time, etc.). Disable with:
$minifier = new Minifier(false); // Disables auto-raising of limits
memory_limit if needed.Source Maps:
$minifier->keepSourceMapComment(true);
Important Comments:
/*! ... */ comments are removed by default (unlike YUI compressor). Re-enable with:
$minifier->removeImportantComments(false);
Line Breaks:
setLineBreakPosition(0) disables line breaks entirely (outputs one long line).Edge Cases:
@media, @keyframes): The package handles nested rules well, but test complex cases (e.g., grid-template-areas).@import: Unquoted URLs with semicolons may break (fixed in v4.1.1+). Example:
@import url(http://example.com/style;param=1.css);
Dry Run (CLI):
Use --dry-run to see stats without modifying files:
./vendor/bin/cssmin -i input.css --dry-run
Test Suite: Run tests to verify behavior:
./vendor/bin/phpunit
Or test a specific case:
./tests/bin/runner -t "test_media_query"
Logging: Add logging to track minification:
$minifier->run($css);
Log::debug('Minified CSS size: ' . strlen($minified) . ' bytes');
PHP Version:
if (version_compare(PHP_VERSION, '7.0.0', '<')) {
$minifier->setMemoryLimit('512M');
}
Batch Processing: For large projects, process files in batches:
$files = glob(public_path('css/*.css'));
$batchSize = 10;
array_chunk($files, $batchSize, function($batch) {
foreach ($batch as $file) {
// Minify each file
}
});
Caching: Cache minified CSS to avoid reprocessing:
$cacheKey = 'minified_' . md5($css);
$minified = Cache::remember($cacheKey, now()->addHours(1), function() use ($minifier, $css) {
return $minifier->run($css);
});
Custom Rules:
Extend the minifier by subclassing tubalmartin\CssMin\Minifier:
class CustomMinifier extends Minifier
{
public function run($css)
{
$css = $this->customPreProcess($css);
return parent::run($css);
}
protected function customPreProcess($css)
{
// Add custom logic (e.g., remove specific comments)
return preg_replace('/\/\* MyComment \*\//', '', $css);
}
}
Pre/Post-Processing: Chain minification with other tools (e.g., Laravel Mix):
// mix.js
mix.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('postcss-url'),
])
.then(() => {
// Call PHP minifier via Node
exec('php artisan css:minify', (error, stdout) => {
console.log('CSS minified:', stdout);
});
});
Custom CLI Arguments:
Extend the CLI tool by modifying vendor/bin/cssmin or creating a wrapper script.
setChunkLength(): Deprecated in v4.0.0 (no effect). Use setLineBreakPosition() instead.keepSourceMap(): Renamed to keepSourceMapComment() in v4.0.0. CLI flag --keep-sourcemap still works.margin: 0) is disabled by default in newer versions. Re-enable by subclassing and overriding logic.How can I help you explore Laravel packages today?