robloach/component-installer
Installer for Composer components like Drupal modules/themes and other webroot packages. Works with Composer’s installer system to place packages into the right directories, supporting component types and custom install paths for legacy CMS structures.
Installation: Add the package via Composer:
composer require robloach/component-installer
Publish the config (optional, but recommended for customization):
php artisan vendor:publish --provider="Robloach\ComponentInstaller\ComponentInstallerServiceProvider"
First Use Case:
Install a web component (e.g., vue for Vue.js):
php artisan component:install vue
This will:
resources/js/components/ (configurable).package.json with the new dependency.Verify:
Check resources/js/components/ for the installed component files and package.json for the new dependency entry.
Component Installation:
php artisan component:install <name> to fetch and install a component from a supported source (e.g., Packagist, GitHub, or a custom registry).php artisan component:install user/repo
(Ensure the config is updated to include GitHub as a source.)Bulk Installation:
php artisan component:install vue,alpinejs,axios
Integration with Build Tools:
npm install && npm run dev
post-install-cmd in composer.json).Custom Component Sources:
Robloach\ComponentInstaller\Contracts\ComponentSource interface.Version Management:
php artisan component:install vue@3.2.45
^ or ~ for flexible versioning (e.g., vue@^3.2).Post-Install Hooks:
component.installed event to run custom logic after installation:
// In EventServiceProvider
protected $listen = [
'component.installed' => [
'App\Listeners\PostComponentInstall',
],
];
Laravel Mix/Vite:
Ensure your build tool is configured to resolve components from resources/js/components/. For Vite, update vite.config.js:
resolve: {
alias: {
'@components': path.resolve(__dirname, './resources/js/components'),
},
},
IDE Support:
Add resources/js/components/ to your IDE’s include path for autocompletion.
Testing: Test installations in a fresh environment or use Docker to avoid conflicts with existing dependencies.
Dependency Conflicts:
component-installer may cause conflicts. Always use the installer for consistency.node_modules and package-lock.json before reinstalling dependencies if conflicts arise.Source Configuration:
sources config array in config/component-installer.php:
'sources' => [
'packagist' => [
'type' => 'packagist',
'url' => 'https://packagist.org',
],
'github' => [
'type' => 'github',
'url' => 'https://github.com',
],
],
Permission Issues:
resources/js/ or package.json will fail.Component Overwrites:
package.json entries.--force cautiously or check for existing entries first.Build Tool Cache:
npm run dev -- --force) to avoid stale builds.Verbose Output:
Use -v or --verbose for detailed logs:
php artisan component:install vue -v
Dry Run:
Test installations without modifying files by temporarily overriding the install method in a custom command or service provider.
Event Listeners:
Debug the component.installed event to trace installation steps:
// In a listener
public function handle($event) {
\Log::info('Component installed:', $event->component);
}
Custom Sources:
Implement Robloach\ComponentInstaller\Contracts\ComponentSource to add support for private registries or internal tools. Example:
namespace App\ComponentSources;
use Robloach\ComponentInstaller\Contracts\ComponentSource;
class PrivateRegistry implements ComponentSource {
public function getComponent($name) {
// Fetch from private registry
}
}
Register it in the config:
'sources' => [
'private' => [
'type' => 'custom',
'class' => App\ComponentSources\PrivateRegistry::class,
],
],
Pre/Post-Install Hooks:
Extend the Robloach\ComponentInstaller\Installers\Installer class to add custom logic before or after installation. Example:
namespace App\Installers;
use Robloach\ComponentInstaller\Installers\Installer;
class CustomInstaller extends Installer {
protected function postInstall($component) {
// Custom logic (e.g., run tests, update docs)
}
}
Bind it in the service provider:
$this->app->bind(
Robloach\ComponentInstaller\Contracts\Installer::class,
App\Installers\CustomInstaller::class
);
Component Naming:
Override the default naming convention (e.g., kebab-case to PascalCase) by extending the Robloach\ComponentInstaller\Installers\Installer and modifying the getComponentPath method.
Testing:
Use the package’s ComponentInstaller facade or service container to test installations in PHPUnit:
$installer = $this->app->make(Robloach\ComponentInstaller\Contracts\Installer::class);
$installer->install('vue');
$this->assertFileExists(resource_path('js/components/vue/index.js'));
How can I help you explore Laravel packages today?