Weave 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

Asset Mapper Laravel Package

symfony/asset-mapper

Symfony AssetMapper exposes asset directories, copies them to a public path with versioned filenames, and dumps an importmap so you can write modern JavaScript without a build system.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation:

    composer require symfony/asset-mapper
    

    For Laravel, manually integrate the component or use Symfony’s AssetMapperBundle if available.

  2. Configuration: Create config/asset_mapper.php with basic settings:

    return [
        'source_dirs' => [
            resource_path('assets'), // Source assets directory
        ],
        'public_dir' => public_path('assets'), // Output directory
        'version_strategy' => 'hash', // 'hash' or 'timestamp'
        'import_map' => [
            'entrypoints' => [
                'app' => ['main.js'], // Entry points for importmap
            ],
        ],
    ];
    
  3. First Command:

    php artisan asset-map:dump
    

    This generates versioned assets (e.g., main.[hash].js) and an importmap.json in the public directory.

  4. Usage in Blade:

    <!-- Versioned asset -->
    <script type="module" src="{{ asset('assets/main.[hash].js') }}"></script>
    
    <!-- Importmap for ES modules -->
    <script type="importmap">
      {
        "imports": {
          "lodash": "/assets/lodash.[hash].js",
          "react": "https://esm.sh/react@18"
        }
      }
    </script>
    
  5. First Use Case: Replace manual versioning (e.g., ?v=1.2) with auto-generated hashes for cache-busting. Enable ES modules for modern JavaScript without a build step.

Where to Look First

  • Symfony Documentation: Official guide for configuration, CLI, and advanced usage.
  • config/asset_mapper.php: Central configuration for source directories, output paths, and versioning.
  • Artisan Commands:
    • asset-map:dump: Generate versioned assets and importmap.
    • asset-map:watch: Auto-rebuild assets during development.
  • public/assets/importmap.json: Auto-generated importmap for ES modules.

Implementation Patterns

1. Asset Versioning and Caching

  • Pattern: Use version_strategy: 'hash' for production to ensure cache-busting filenames (e.g., styles.[hash].css).
  • Integration:
    • Configure in config/asset_mapper.php:
      'version_strategy' => env('APP_ENV') === 'prod' ? 'hash' : 'timestamp',
      
    • Blade Helper: Create a helper to generate versioned URLs:
      // app/Helpers/AssetMapperHelper.php
      function versioned_asset($path) {
          $mapper = app(\Symfony\Component\AssetMapper\AssetMapper::class);
          return $mapper->getUrl($path);
      }
      
      Usage:
      <link rel="stylesheet" href="{{ versioned_asset('css/app.css') }}">
      

2. Importmap for ES Modules

  • Pattern: Use import_map to define entry points and external dependencies.
  • Integration:
    • Configure in config/asset_mapper.php:
      'import_map' => [
          'entrypoints' => [
              'app' => ['main.js'],
              'admin' => ['admin.js'],
          ],
          'imports' => [
              'lodash' => 'https://esm.sh/[email protected]',
          ],
      ],
      
    • Dynamic Importmap: Use the AssetMapper service to generate the importmap dynamically in a controller:
      use Symfony\Component\AssetMapper\AssetMapper;
      use Symfony\Component\AssetMapper\ImportMap\ImportMap;
      
      public function getImportmap(AssetMapper $mapper) {
          $importMap = $mapper->getImportMap();
          return response()->json($importMap->toArray());
      }
      

3. Development Workflow with asset-map:watch

  • Pattern: Use asset-map:watch for live reloading during development.
  • Integration:
    • Run in a terminal:
      php artisan asset-map:watch
      
    • Configure in config/asset_mapper.php:
      'watch' => [
          'patterns' => ['resources/assets/**/*'],
      ],
      
    • Laravel Mix/Vite: Replace mix-manifest.json with the auto-generated importmap.json for ES modules.

4. Custom Version Strategies

  • Pattern: Extend the version strategy for custom logic (e.g., semantic versioning).
  • Integration:
    • Create a custom version strategy class:
      // app/Services/CustomVersionStrategy.php
      use Symfony\Component\AssetMapper\VersionStrategy\VersionStrategyInterface;
      
      class CustomVersionStrategy implements VersionStrategyInterface {
          public function getVersion(string $path): string {
              return filemtime($path);
          }
      }
      
    • Register in config/asset_mapper.php:
      'version_strategy' => \App\Services\CustomVersionStrategy::class,
      

5. Integration with Laravel Mix/Vite

  • Pattern: Use asset-map:dump as a post-processing step for Laravel Mix or Vite.
  • Integration:
    • Add to webpack.mix.js:
      mix.postCss('resources/css/app.css', 'public/assets/css', [
          // PostCSS config
      ])
      .then(() => {
          require('child_process').execSync('php artisan asset-map:dump');
      });
      
    • For Vite, use a build hook in vite.config.js:
      import { defineConfig } from 'vite';
      import laravel from 'laravel-vite-plugin';
      
      export default defineConfig({
          plugins: [
              laravel({
                  input: ['resources/js/app.js'],
                  refresh: true,
              }),
          ],
          build: {
              rollupOptions: {
                  output: {
                      assetFileNames: 'assets/[name].[hash][extname]',
                  },
              },
          },
      });
      
    • Run asset-map:dump after Vite builds:
      npm run dev && php artisan asset-map:dump
      

6. Handling CSS and JSON Imports

  • Pattern: Leverage the component’s support for CSS @import and JSON imports.
  • Integration:
    • Ensure CSS files use relative paths for @import:
      @import url('./variables.css');
      
    • Use JSON imports in JavaScript:
      import data from './data.json';
      
    • Configure in config/asset_mapper.php:
      'import_map' => [
          'entrypoints' => [
              'app' => ['main.js'],
          ],
          'imports' => [
              './data.json' => '/assets/data.[hash].json',
          ],
      ],
      

Gotchas and Tips

Pitfalls

  1. Missing or Incorrect Source Directories:

    • Issue: Assets not being processed if source_dirs is misconfigured.
    • Fix: Verify paths in config/asset_mapper.php and ensure they exist:
      'source_dirs' => [
          resource_path('assets'), // Correct path
          // base_path('vendor/foo/bar') // Example of external dependency
      ],
      
  2. Circular Imports in CSS/JS:

    • Issue: Infinite loops during asset mapping if files import each other.
    • Fix: Use the --dry-run flag to debug:
      php artisan asset-map:dump --dry-run
      
    • Symfony Fix: The component now includes a sequence parser to handle circular imports (v7.3+).
  3. Importmap Polyfill Issues:

    • Issue: CSP (Content Security Policy) errors with the importmap polyfill.
    • Fix: Exclude the nonce from the polyfill body (fixed in v8.0.10+):
      'import_map' => [
          'polyfill' => false, // Disable if using a custom polyfill
      ],
      
  4. Version Strategy Conflicts:

    • Issue: Using timestamp in production can break caching.
    • Fix: Always use hash in production:
      'version_strategy' => env('APP_ENV') === 'prod' ? 'hash' : 'timestamp',
      
  5. Duplicate Entries in Importmap:

    • Issue: Duplicate entries in the importmap causing errors.
    • Fix: Update to v7.3.4+ which prevents duplicates:
      composer update symfony/asset-mapper
      
  6. Case Sensitivity in File Paths:

    • Issue: Case-sensitive filesystem issues (e.g., Linux vs. Windows).
    • Fix: Normalize paths in config/asset_mapper.php:
      'source_dirs' => [
          strtolower(resource_path('assets')),
      ],
      
  7. Orphaned Assets After a Failed Compiler:

    • Issue: When a compiler (e.g., a CSS @import resolver or a custom compiler) throws mid-run, the previously written output file could be left behind in public_dir, producing a stale/partial asset that still resolves via the importmap.
    • Fix: v8.1.9 (bug #66645) now cleans up the asset being created when a compiler fails, so failed builds no longer leak half-written files. If you are pinned below 8.1.9, either upgrade:
      composer update symfony/asset-mapper
      
      or clear the output directory before dumping in CI:
      rm -rf public/assets && php artisan asset-map:dump
      
    • Debugging tip: Compiler exceptions surface during asset-map:dump, not at request time — always fail the CI step on a non-zero exit code so a broken asset never gets deployed.

Tips

  • Pin the patch version in CI: bugfix releases in the 8.1.x line (like 8.1.9) change on-disk build output behavior; run asset-map:dump fresh in CI rather than caching public/assets between jobs.
  • Prefer hash over filemtime: the timestamp strategy is deterministic-per-machine and will churn your importmap across deploy hosts.
  • Watch the importmap, not just the files: after any upgrade, diff public/assets/importmap.json — orphaned or newly-hashed entries are the fastest signal something changed in how assets are compiled.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource