jbzoo / assets
Manage any asset files (js, css, less) and their depending + compressing and merging
Installs: 54 908
Dependents: 1
Suggesters: 0
Security: 0
Stars: 3
Watchers: 3
Forks: 0
Open Issues: 0
Requires
- php: ^8.2
- jbzoo/data: ^7.2
- jbzoo/less: ^7.0.1
- jbzoo/path: ^7.0.1
- jbzoo/utils: ^7.3
Requires (Dev)
- jbzoo/toolbox-dev: ^7.2
- symfony/filesystem: >=7.3.2
README
A PHP library for managing asset files (JavaScript, CSS, LESS, JSX) with dependency resolution, compression, and merging capabilities. The library provides automatic type detection, dependency management, and a flexible build system for modern web applications.
Installation
composer require jbzoo/assets
Quick Start
use JBZoo\Assets\Manager; use JBZoo\Path\Path; // Initialize path resolver and asset manager $path = new Path(); $path->set('assets', '/path/to/your/assets'); $manager = new Manager($path); // Register and queue assets $manager ->register('jquery', 'assets/js/jquery.js') ->register('bootstrap-css', 'assets/css/bootstrap.css') ->register('app', 'assets/js/app.js', ['jquery']) // depends on jquery ->add('bootstrap-css') ->add('app'); // Build assets with dependency resolution $assets = $manager->build(); // Output: Array with organized asset types // $assets['js'] contains JavaScript files // $assets['css'] contains CSS files
Supported Asset Types
File-based Assets
The library automatically detects asset types by file extension:
// JavaScript files (.js) $manager->register('script', 'assets/js/script.js'); // CSS files (.css) $manager->register('styles', 'assets/css/styles.css'); // LESS files (.less) $manager->register('theme', 'assets/less/theme.less'); // JSX files (.jsx) $manager->register('component', 'assets/jsx/component.jsx');
Code-based Assets
Include inline code directly:
use JBZoo\Assets\Asset\AbstractAsset; // Inline CSS $manager->register('inline-css', 'div { color: red; }', [], [ 'type' => AbstractAsset::TYPE_CSS_CODE ]); // Inline JavaScript $manager->register('inline-js', 'console.log("Hello World");', [], [ 'type' => AbstractAsset::TYPE_JS_CODE ]); // Code with HTML tags (automatically stripped) $manager->register('styled', '<style>body { margin: 0; }</style>', [], [ 'type' => AbstractAsset::TYPE_CSS_CODE ]);
External Assets
// CDN resources $manager->register('jquery-cdn', 'https://code.jquery.com/jquery-3.6.0.min.js'); // External stylesheets $manager->register('bootstrap-cdn', 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css');
Callback Assets
Execute custom logic during the build process:
// Simple callback $manager->register('analytics', function() { return 'ga("send", "pageview");'; }); // Multiple callbacks in collection $manager->add('init-scripts', [ function() { return 'console.log("Script 1");'; }, function() { return 'console.log("Script 2");'; }, function() { return 'console.log("Done");'; } ]);
Dependency Management
Basic Dependencies
// jQuery must load before Bootstrap JavaScript $manager ->register('jquery', 'assets/js/jquery.js') ->register('bootstrap-js', 'assets/js/bootstrap.js', ['jquery']) ->add('bootstrap-js'); // jQuery will be included automatically
Complex Dependency Trees
$manager ->register('utilities', 'assets/js/utils.js') ->register('jquery', 'assets/js/jquery.js') ->register('plugin', 'assets/js/plugin.js', ['jquery', 'utilities']) ->register('app', 'assets/js/app.js', ['plugin']) ->add('app'); // Build order: utilities, jquery, plugin, app
Circular Dependency Detection
try { $manager ->register('a', 'a.js', ['b']) ->register('b', 'b.js', ['a']) // Circular dependency ->add('a'); $manager->build(); // Throws exception } catch (\JBZoo\Assets\Exception $e) { echo "Circular dependency detected: " . $e->getMessage(); }
Path Resolution
Virtual Paths
$path = new Path(); $path->set('assets', '/var/www/assets'); $path->set('vendor', '/var/www/vendor'); $manager = new Manager($path); // Use virtual paths $manager->register('app', 'assets:js/app.js'); // Resolves to /var/www/assets/js/app.js $manager->register('lib', 'vendor:lib/script.js'); // Resolves to /var/www/vendor/lib/script.js
Relative and Absolute Paths
// Relative to current working directory $manager->register('local', 'js/local.js'); // Absolute path $manager->register('system', '/usr/share/js/system.js');
Configuration Options
Debug Mode
$manager = new Manager($path, ['debug' => true]); // Or set later $manager->setParam('debug', true);
Strict Mode
$manager = new Manager($path, ['strict_mode' => true]); // Throws exceptions for missing files $manager->register('missing', 'assets/js/missing.js'); $manager->add('missing'); $manager->build(); // Exception thrown
LESS Compilation Options
$manager = new Manager($path, [ 'less' => [ 'compress' => true, 'sourceMap' => false ] ]);
Building and Output
Basic Build
$assets = $manager->build(); // Result structure: [ 'js' => ['path/to/script1.js', 'path/to/script2.js'], 'js_code' => ['console.log("inline");'], 'jsx' => ['path/to/component.jsx'], 'jsx_code' => ['ReactDOM.render(...);'], 'css' => ['path/to/styles.css'], 'css_code' => ['body { margin: 0; }'], 'callback' => [42, 'result', ...] // Callback return values ]
Processing Build Results
$assets = $manager->build(); // Generate HTML tags foreach ($assets['css'] as $cssFile) { echo '<link rel="stylesheet" href="' . $cssFile . '">' . PHP_EOL; } foreach ($assets['js'] as $jsFile) { echo '<script src="' . $jsFile . '"></script>' . PHP_EOL; } // Include inline styles if (!empty($assets['css_code'])) { echo '<style>' . implode("\n", $assets['css_code']) . '</style>'; } // Include inline scripts if (!empty($assets['js_code'])) { echo '<script>' . implode("\n", $assets['js_code']) . '</script>'; }
Asset Collections
Grouping Related Assets
// Register a collection of related assets $manager->add('ui-components', [ 'assets/css/buttons.css', 'assets/css/modals.css', 'assets/js/components.js' ]);
Managing Asset Queues
// Add assets to queue $manager ->add('jquery') ->add('bootstrap') ->add('app'); // Remove from queue (but keep registered) $manager->remove('bootstrap'); // Unregister completely $manager->unregister('app');
Advanced Usage
Custom Asset Types
// Register custom asset type $manager->getFactory()->registerType('custom', CustomAssetClass::class); // Use custom type $manager->register('special', 'data', [], ['type' => 'custom']);
Conditional Asset Loading
$isProduction = $_ENV['APP_ENV'] === 'production'; if ($isProduction) { $manager->register('analytics', 'assets/js/analytics.min.js'); } else { $manager->register('debug-tools', 'assets/js/debug.js'); }
Asset Preprocessing
$manager->register('processed', function() use ($dataProcessor) { $data = $dataProcessor->compile(); return "window.appData = " . json_encode($data) . ";"; });
Error Handling
try { $manager ->register('app', 'missing-file.js') ->add('app'); $assets = $manager->build(); } catch (\JBZoo\Assets\Exception $e) { // Handle missing files, circular dependencies, etc. error_log("Asset error: " . $e->getMessage()); }
Requirements
- PHP 8.2 or higher
- JBZoo Utils package
- JBZoo Path package
- JBZoo Data package
- JBZoo Less package (for LESS file support)
Testing
# Run all tests make test make codestyle
License
MIT