tito10047/asset-mapper-test-bundle
A Symfony test bundle for AssetMapper that provides helpers and assertions for verifying asset mapping behavior in your test suite. Use it to check that mapped assets resolve, render, and compile correctly, making it easier to write reliable integration tests for asset handling without manual setup.
What this package is (and isn't). Despite being reviewed in a Laravel/PHP context, asset-mapper-test-bundle is a Symfony-style bundle that bridges Symfony AssetMapper importmap output into a Node.js test runner. It is not a Laravel package and has no first-party Laravel/Blade/Vite integration. That framing matters for the architecture-fit decision below.
Architecture fit. The bundle solves a real, narrow problem: AssetMapper resolves vendor JS via importmap paths that Node cannot follow, so JS unit tests fail with ERR_MODULE_NOT_FOUND. The package generates node_modules/<pkg>/index.js + package.json shims (or symlinks) so Vitest/Jest can resolve the same specifiers the browser uses. Fit is strong only if we (a) run AssetMapper as the front-end asset pipeline and (b) run Node-based JS tests in CI. In a standard Laravel stack (Vite + @vite directive), this package provides no value.
Release 0.2.2 assessment. Patch-level, four bug fixes, no new features, no deprecations, no API surface changes. Two of the fixes are materially de-risking rather than cosmetic:
assets/vendor/ was corrupting project source assets — a CSS/subpath entry could write index.js/package.json through a directory symlink and permanently contaminate tracked source. This is the highest-severity item and is now fixed.<basename>.index.js vendor naming (e.g. @hotwired/stimulus → stimulus.index.js) previously produced unresolvable directories; now resolves correctly for both symlink and loader variants. This is the most common real-world vendor layout, so the package is now usable on typical Stimulus/UX-style dependency trees.type: 'css' importmap entries are skipped, preventing a CSS entry from shadowing the package's real JS entry at node_modules/<pkg>/index.js.index.js and never resolved the subpath specifier anyway.Technical risk. Remaining risk is low but non-zero and structurally concentrated: the tool writes into node_modules/ and, pre-0.2.2, could write into source. On 0.2.2 the destructive path is closed. Residual risks: (1) shim staleness when importmap.php changes without re-running the generator; (2) silent skip of CSS and subpath entries means a test importing a subpath specifier (jquery-ui/ui/widgets/sortable) will now fail loudly rather than mis-resolve — an improvement, but it moves the failure to test-run time; (3) bus-factor of one on a community bundle.
Key questions to resolve before adopting.
importmap.php subpath imports (jquery-ui/...) in current code? Those are explicitly unsupported in the symlink variant.node_modules hygiene) or loader (more explicit, more files)?Stack fit. This slots into a Symfony AssetMapper + Node test-runner combination. For a Laravel shop the realistic entry paths are: (1) we don't adopt — correct answer if we're Vite-based; (2) we adopt inside a Symfony service or a Symfony-based admin/back-office component that co-exists with a Laravel app; (3) we treat it as a reference implementation and hand-roll equivalent shim generation in our own tooling. Path (3) is worth pricing out, since the problem (importmap → Node resolution) is ~200 lines of generation logic.
Migration path. Greenfield-friendly, brownfield-careful. For existing projects: install and pin ^0.2.2, run generation in a dry-run/inspect mode first if available, and diff node_modules/ plus git status on assets/vendor/ before and after. The assets/vendor/ cleanliness check is the acceptance gate — if anything under source control changes, stop.
Compatibility. Patch release, no breaking changes from 0.2.1. Behavior deltas to expect on upgrade: packages previously "resolving" via a CSS shadow will now resolve to the real JS entry (tests may start passing that were quietly wrong, or start failing where the entry shape differs); subpath imports that appeared to work in the symlink variant will now error — these were never resolving the subpath specifier, so treat any such test as newly-uncovered. PHP version and Symfony/AssetMapper version floors should be confirmed against the composer constraint and recorded in the ADR.
Sequencing.
importmap.php for type: 'css' entries and subpath imports; these define the blast radius of the 0.2.2 behavior changes.^0.2.2; add a git status --porcelain assets/vendor/ assertion to CI so the pre-0.2.2 corruption class can never silently return.<basename>.index.js vendor (e.g. @hotwired/stimulus) to lock in the headline fix.Maintenance. Low ongoing effort, but it is a generated-artifact tool, so the maintenance burden is really "keep the generator in the test pipeline" plus periodic version bumps. Do not vendor or commit the generated node_modules shims. Budget a small quarterly check against upstream releases; the changelog is well-written and specific, which lowers review cost per bump.
Support. Community-maintained, single-maintainer signal, no commercial backing. Acceptable for dev-time test tooling where failure blocks CI but never touches production. Unacceptable as a load-bearing part of a release pipeline without an internal owner named. Recommend: one named engineer owns the pin, and a documented 2-hour workaround ("hand-write the two shim files for the failing package") so a stalled upstream isn't a release blocker.
Scaling. Scales linearly with vendor-package count — each importmap entry produces a small shim. No runtime cost in production: this is strictly test-time and dev-time tooling, so it does not affect request latency, deploy size, or prod surface. The symlink variant scales better on file count and CI cache churn; the loader variant scales better on transparency and debuggability. Large monorepos with many vendors should prefer the loader variant and accept the extra generated files.
Failure modes.
exports/imports fields and nested chunk files are the next likely frontier given the 0.2.x trajectory; budget for one or two more patch bumps before calling it stable.Ramp-up. Roughly half a day for an engineer already fluent in AssetMapper and the test runner; 1–2 days including the importmap inventory and CI guard for someone new. No new language or runtime is introduced beyond Node, which the team already has. Documentation burden is low — but write the ADR anyway, because the "why do we generate files in node_modules/?" question will be asked by the next person who sees it.
Verdict. 0.2.2 is a meaningful quality release, not a feature release: it converts a source-corruption hazard and a common-layout resolution failure into working behavior. It materially improves adoptability. It does not change the strategic picture — this remains a narrow, single-purpose, community-maintained bridge whose value is entirely contingent on running Symfony AssetMapper with Node-based JS tests. Adopt at ^0.2.2 in that context, with an internal owner and a source-asset cleanliness gate in CI; decline cleanly otherwise.
How can I help you explore Laravel packages today?