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

Webpack Bundle Laravel Package

maba/webpack-bundle

Symfony bundle that integrates Webpack into your application, offering Twig helpers and services to load compiled assets, resolve manifest entries, and use the Webpack dev server. Simplifies asset bundling and cache-busting in Symfony projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Start with the reality check: maba/webpack-bundle is a Symfony bundle (Maba\Bundle\WebpackBundle). There is no WebpackServiceProvider, no Blade directive, no artisan command, and no config/webpack.mix.js. If you are building a Laravel-only app, the correct day-to-day answer is "use Vite or Laravel Mix." The package is worth your time only in one scenario: you like its manifest contract and Twig helper semantics and want to port them to Blade, or you work in a shop that has both a Symfony app and a Laravel app and want one shared Webpack build output.

If you proceed, here is the minimal path:

composer require maba/webpack-bundle

Register it in config/bundles.php, then configure manifest location:

# config/packages/maba_webpack.yaml
maba_webpack:
    paths:
        - '%kernel.project_dir%/public/build/manifest.json'

That manifest is the whole contract: a JSON map of entry name → { js: [...], css: [...] } (or a flat file list, depending on the plugin generating it). The bundle's job is to read that file and emit <script> / <link> tags per entry, with correct hashed filenames.

Where to look first: the README's Twig examples (webpack_entry_js_files, webpack_entry_css_files, webpack_entry_script_tags, webpack_entry_link_tags), then DependencyInjection/Configuration.php for the real config keys, then the Twig extension and manifest reader classes — those two files are what you will reimplement in Laravel.

First use case to port: a Blade directive that renders every JS/CSS file for a named entry, so a controller returns view('dashboard') and the layout calls @webpackEntry('dashboard'). Do this before touching dev-server or hot-reload features.

Implementation Patterns

One entry per page, plus a shared vendor entry. This is the pattern the bundle is built around and the one worth copying. webpack.config.js declares app, vendor, dashboard, checkout; the manifest tells PHP which hashed files each one needs.

Port the reader, not the bundle. A small Laravel service is enough:

// app/Support/WebpackManifest.php
class WebpackManifest
{
    private ?array $data = null;

    public function __construct(private string $path) {}

    public function entry(string $name): array
    {
        $this->data ??= json_decode(file_get_contents($this->path), true, flags: JSON_THROW_ON_ERROR);

        // webpack-manifest-plugin v2/v3: { "app.js": "/build/app.abc.js" }
        // webpack-assets-manifest / newer formats: { "app": { "js": [...], "css": [...] } }
        if (isset($this->data[$name]) && is_array($this->data[$name])) {
            return $this->data[$name] + ['js' => [], 'css' => []];
        }

        return ['js' => array_values(array_filter(
            $this->data, fn ($v, $k) => str_starts_with($k, $name.'.') && str_ends_with($k, '.js'), ARRAY_FILTER_USE_BOTH
        )), 'css' => []];
    }
}

Bind it as a singleton with the manifest path from config('webpack.manifest').

Blade directives mirroring the Twig helpers:

Blade::directive('webpackEntry', fn ($expr) => "<?php echo app(\App\Support\WebpackManifest::class)->entry($expr)['js'] ... ?>");

Keep two directives (@webpackScripts, @webpackStyles) rather than one mega-directive — you will want scripts in <head> with defer and styles separately, exactly as webpack_entry_script_tags / webpack_entry_link_tags split them in Twig.

Split JS and CSS consumers. Not every entry has CSS. Return empty arrays, not null, and let the directive emit nothing. This is what the bundle does and it is why webpack_entry_css_files('app') is safe to call on a JS-only entry.

Dev vs production via env, not code. Point webpack.manifest at a dev manifest in local and the hashed production manifest in CI. Never branch on app()->environment() inside the reader; the manifest itself is the switch.

Cache-busting is the manifest's job, not Laravel's. Do not append ?v=filemtime(). The hashed filename in the manifest is your cache key. If you find yourself adding query strings, you have two cache layers fighting.

CI ordering: npm ci && npm run production before php artisan config:cache and before whatever copies public/build into the release. The manifest must exist at boot time if you bind its path eagerly.

Gotchas and Tips

  • Last release is January 2020. Expect Symfony 4/5-era assumptions and PHP 7.x idioms. On PHP 8.2+ with Symfony 6, Composer constraints may block install outright. Check composer why-not before planning around it.
  • Manifest format drift is the number-one failure. webpack-manifest-plugin changed its output shape across major versions (entrypoints as object vs. array; flat file map vs. per-entry object). The bundle was written against one of them. Log the decoded manifest once during setup and match your reader to what you actually see — do not match it to a blog post.
  • Webpack 5 vs. Webpack 4. The bundle predates the Webpack 5 default asset module behaviour. If your entries come out with asset/resource paths the reader does not expect, that is a build-side problem, not a PHP-side one.
  • Missing entry behaviour. Decide explicitly whether an unknown entry throws or renders empty. Silent empty renders are how you ship a page with no JS and spend an hour in the network tab. Throw in non-production.
  • Public path vs. filesystem path. The manifest usually stores /build/app.abc.js (URL). Do not run it through asset() blindly — you may double-prefix or lose a CDN base. If you need a CDN, rewrite the prefix in one place in the reader.
  • Do not commit the manifest unless you have a deliberate reason. It is a build artefact; committing it produces merge conflicts and stale-entry bugs. Generate it in CI and deploy it with the release.
  • Extension point if you stay on Symfony: override the manifest reader / Twig extension service rather than forking. That is the seam the bundle exposes, and it is the same seam you would copy for Laravel.
  • Testing: assert against a fixture manifest, not the real build. A tests/fixtures/manifest.json with one entry containing both JS and CSS covers 90% of your reader's branches and keeps tests green without Node installed.
  • Blade escaping: if you build tag strings inside a directive, remember Blade will not escape <?php ?> output but your attributes can still be injected from entry names. Whitelist entry names or escape attributes.
  • Bottom line for scoring: high opportunity, low maintenance. Borrow the manifest contract and helper split; do not expect the bundle itself to survive a Laravel upgrade cycle.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo