Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Grunt Hash Assets Bundle Laravel Package

agallou/grunt-hash-assets-bundle

Symfony bundle adding a Twig grunt_asset() function to reference files renamed by grunt-hash (e.g., main.54e79f6f.css). Looks up matching hashed assets in web/assets and returns the correct /assets URL; throws if missing or ambiguous.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle Add the package via Composer in your Laravel project (though technically designed for Symfony, it can be adapted):

    composer require agallou/grunt-hash-assets-bundle
    

    Register the bundle in config/bundles.php (Symfony) or manually load it in Laravel’s service provider.

  2. Configure the Bundle Publish the default config (if available) or define it in config/packages/grunt_hash_assets.yaml (Symfony) or config/grunt_hash_assets.php (Laravel):

    return [
        'assets_dir' => public_path('assets'),
        'assets_base_path' => '/assets',
    ];
    
  3. Run Grunt Ensure grunt-hash is installed in your project’s package.json:

    npm install grunt-hash --save-dev
    

    Configure Grunt to hash assets (see grunt-hash docs) and run:

    grunt hash
    
  4. Use the Twig Function In your Blade templates (or Twig if using Symfony), leverage the grunt_asset function:

    <link rel="stylesheet" href="{{ grunt_asset('css/main.css') }}">
    

    This resolves to /assets/main.[hash].css dynamically.


Implementation Patterns

Workflow Integration

  1. Asset Pipeline

    • Preprocessing: Use Grunt (or Laravel Mix) to concatenate/minify assets before hashing.
    • Hashing: Run grunt hash in your build pipeline (e.g., post-build in package.json or Laravel’s post-autoload-dump).
    • Serving: The bundle’s Twig function handles hashed filenames transparently.
  2. Laravel-Specific Adaptations

    • Blade Compatibility: Create a custom Blade directive or helper to mimic grunt_asset:
      // app/Helpers/AssetHelper.php
      if (!function_exists('grunt_asset')) {
          function grunt_asset($path) {
              $config = config('grunt_hash_assets');
              $files = glob($config['assets_dir'] . '/' . $path);
              if (count($files) !== 1) {
                  throw new \RuntimeException("No or multiple files found for: {$path}");
              }
              return $config['assets_base_path'] . '/' . basename($files[0]);
          }
      }
      
    • Service Provider: Bind the helper in AppServiceProvider@boot():
      require app_path('Helpers/AssetHelper.php');
      
  3. Caching Strategies

    • Versioned Assets: Use hashed filenames for cache busting (e.g., main.54e79f6f.css).
    • CDN-Friendly: Configure assets_base_path to match your CDN endpoint (e.g., /cdn/assets).
  4. Dynamic Asset Loading

    • Environment-Specific Paths: Override assets_dir in config/grunt_hash_assets.php per environment:
      'assets_dir' => env('ASSET_PATH', public_path('assets')),
      
    • Fallbacks: Handle missing files gracefully (e.g., return a default path or throw a custom exception).

Gotchas and Tips

Pitfalls

  1. File Naming Conflicts

    • Issue: Multiple files match main*.css (e.g., main.min.css and main.css).
    • Fix: Use unique patterns (e.g., main.[hash].css) or enforce naming conventions in your build process.
  2. Grunt Configuration Mismatch

    • Issue: Grunt hashes files, but the bundle can’t find them due to path discrepancies.
    • Fix: Ensure assets_dir in the bundle config matches Grunt’s output directory (e.g., dist/ vs. web/assets/).
  3. Blade vs. Twig

    • Issue: The bundle assumes Twig; Laravel’s Blade requires a workaround (see Implementation Patterns).
    • Fix: Use the custom helper or switch to Twig if Twig integration is critical.
  4. Case Sensitivity

    • Issue: Filesystem paths may be case-sensitive (e.g., Main.css vs. main.css).
    • Fix: Normalize paths in the bundle’s logic or enforce consistent casing in your build.

Debugging Tips

  1. Verify Grunt Output

    • Check if files are hashed correctly by running:
      grunt hash --verbose
      
    • Inspect the output directory manually to confirm filenames.
  2. Log Bundle Behavior

    • Add debug logs in the bundle’s Twig extension or custom helper:
      \Log::debug('Searching for files in:', [$config['assets_dir'], $path]);
      
  3. Test Edge Cases

    • No Files: Simulate missing assets to ensure exceptions are caught.
    • Spaces/Special Chars: Test paths with spaces or special characters (e.g., my asset.css).

Extension Points

  1. Custom Hashing Logic

    • Override the Twig function to support additional features (e.g., query strings for non-hashed assets):
      {{ grunt_asset('css/main.css', { hash: false }) }}
      
  2. Asset Manifests

    • Integrate with Laravel Mix’s manifest (e.g., mix-manifest.json) for more robust asset resolution:
      $manifest = json_decode(file_get_contents(public_path('mix-manifest.json')), true);
      return $manifest[$path] ?? $path;
      
  3. Symfony-Laravel Hybrid

    • If using Symfony components in Laravel, leverage the bundle natively and wrap Twig functions in a facade:
      // app/Facades/GruntAsset.php
      public static function asset($path) {
          return app('grunt_hash_assets.twig')->getFunction('grunt_asset')->getCallable()($path);
      }
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours