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 Composer Bundle Laravel Package

jbsnewmedia/asset-composer-bundle

A PHP bundle for composing and managing frontend assets, helping you organize, combine, and serve CSS and JavaScript files from a central configuration. It streamlines asset handling in Symfony-style applications, reducing repetitive markup and keeping templates cleaner.

View on GitHub
Deep Wiki
Context7

Getting Started

This release moves the baseline to PHP 8.4 and adds Symfony 8 support, so before anything else verify your runtime:

php -v                       # must be >= 8.4 to install 1.2.0
composer require jbsnewmedia/asset-composer-bundle:^1.2

If you are still on PHP 8.1–8.3 you either stay on the 1.1.x line or upgrade the runtime first — the constraint is hard, Composer will refuse the install. On Laravel projects this is usually the deciding factor: an app still on PHP 8.2/8.3 cannot take this release until the whole stack (CI image, Forge/Ploiid/Vapor runtime, local Docker) is bumped together.

First look at:

  1. The README — this release specifically expanded the Composer and local-asset examples for Twig in English and German. That is now the fastest path to a working snippet.
  2. The bundle registration (config/bundles.php in Symfony, or your bundle provider list) and any package/config file that points the bundle at your vendor directory.
  3. The Twig extension itself — that is the surface you will actually call from templates.

First use case, in order of value:

  • Assets shipped inside a Composer package — you want a CSS/JS/SVG file that lives in vendor/acme/widget/Resources/public/... rendered through Twig with a cache-busted, correct URL, instead of copying it into your own public/ folder by hand.
  • Local path repositories — a monorepo or a locally developed package symlinked into vendor/ via a Composer path repository. This release is the one that makes that workflow stop throwing containment exceptions, so it is the right thing to test first after upgrading.

Implementation Patterns

Composer-package assets as first-class template citizens. Once the bundle is registered and pointed at your vendor dir, templates reference package assets directly instead of duplicating them. Keep the package name in the path so intent is obvious to reviewers, and treat the vendor path as read-only — never edit assets there, because composer install will overwrite them.

Path-repository / monorepo development. With 1.2.0 the containment check runs through assertFileInsideProjectDir() after resolution, with separators and trailing slashes normalized. That means a composer.json entry like:

"repositories": [{ "type": "path", "url": "../packages/acme-widget" }]

resolves cleanly even though the real path leaves the project root via a symlink. The practical pattern is: develop the package in its own directory, symlink it in, edit live, and let the bundle serve the asset — no more "works only after composer install --no-symlink" dance.

Separate environments, separate expectations. The traversal guard rejects any path containing .. outright with BadRequestHttpException, before touching the filesystem. That is a deliberate design choice with a behavioural consequence: it is deterministic and cheap, but it is also indiscriminate. Build any asset path from a fixed package name plus a fixed relative segment, and let the bundle do the joining — do not pass user-influenced strings through it at all.

Integration tip: front-end build output. A common shape is a package that compiles SCSS/TS on its own and exposes the built file under its public directory. Let the package's CI publish the build artefact into the package, and let this bundle reference it. That keeps your application's public/build clean and makes the package independently versioned.

Upgrade sequencing for existing installs. Because PHP 8.4 is mandatory, do the runtime bump as its own deploy, verified in CI, before bumping this bundle. Then bump to ^1.2 and run the asset-facing test suite. If you use Symfony 8 anywhere, this is the release that unlocks it; 6.4 and 7.x continue to work unchanged.

Gotchas and Tips

  • PHP 8.4 is breaking, not advisory. Dropping 8.1–8.3 support is the headline risk in this release. Pin ^1.1 explicitly if you cannot move yet — an unpinned ^1.0 constraint will simply fail to resolve on older runtimes, which is noisy but not dangerous. The dangerous case is a CI matrix where one job still runs 8.3.
  • Do not "clean up" paths containing ... The new check rejects them before resolution, so a previously-tolerated path like foo/../bar/asset.css that happened to normalise to a valid file will now 400. Grep templates and config for .. segments before deploying; this is the most likely silent regression.
  • Symlink support is intentional, not a hole. assertFileInsideProjectDir() normalises separators and trailing slashes so path repositories resolve. If you see a containment BadRequestHttpException on a legitimately symlinked vendor dir, check that the symlink target itself is sane — the check is now symlink-aware, so a failure usually means a genuinely odd path (relative symlink loops, mixed-separator Windows-style paths in a Linux container, or a bind mount the process cannot realpath).
  • BadRequestHttpException is a 400, not a 500. If traversal attempts are hitting your error tracker as server errors, they are likely being wrapped by a middleware or listener. Log them at warning level and consider alerting on the volume rather than the individual event — a burst is the interesting signal.
  • Debugging resolved paths. The resolution-then-assert order means a failure can come from either stage. Temporarily log the resolved absolute path just before the assertion to distinguish "file not found / wrong vendor dir" from "resolved but outside the project root"; the two look identical from the exception message alone.
  • Extension point. The containment logic is now a named, single-responsibility method (assertFileInsideProjectDir()), which makes it the natural override or decoration point if you need different trust boundaries (e.g. allowing a read-only shared asset mount). Prefer decorating over forking, so you keep picking up the security fixes that this release series is clearly prioritising.
  • Docs are a feature here. The expanded English/German README covers the Composer and local-asset workflows that were previously trial-and-error. If you were maintaining internal notes on how to wire this up, replace them with a link and a note about your own directory conventions — that is one less thing to drift.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
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