Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

axtg's avatar
Level 5

Split webpack bundles by param

So admitted, Webpack (Laravel Mix) is kind of a black box for me. Now recently I tried to dive into it, because I'm annoyed that all my Vue files get loaded all the time.

I have a concrete use case that I am unable to figure out by myself.

  1. In my master template I include the remote Stripe library for payment
  2. In one (and only one) of my Vue files, I refer to this library (authenticated users only)
  3. I tried making the Stripe library inclusion conditional by wrapping it inside @auth @endauth

But then the whole site breaks, because 'CreateSubscription.vue' is trying to call the Stripe function.

Can I somehow split (at least) the CreateSubscription.vue out of the whole package and include it only when its needed? Or anything else that allows me to reduce the overhead of Stripe (at least for non authenticated users)?

Thanks!

0 likes
3 replies
rodrigo.pedra's avatar

Laravel mix can extract all vendor packages into a separate JS file by using mix.extraxt(), see its docs:

https://laravel-mix.com/docs/5.0/extract

Extracting a single Vue component is more tricky as it depends on your code organization. You should have several entry points and call mix.js(...) for each of them. Below is an example I used in one project.

mix.js('resources/assets/js/components/queue/index.js', 'public/js/components/queue.js');
mix.js('resources/assets/js/components/action/index.js', 'public/js/components/action.js');
mix.js('resources/assets/js/components/workflow/index.js', 'public/js/components/workflow.js');
mix.js('resources/assets/js/components/tag/index.js', 'public/js/components/tag.js');

And here is a sample index.js file (tag/index.js):

import Vue from 'vue';

import TagForm from '@/js/components/tag/TagForm';
import TagLabel from '@/js/components/tag/TagLabel';
import TagContent from '@/js/components/tag/TagContent';
import TagsList from '@/js/components/tag/TagsList';

Vue.component('TagForm', TagForm);
Vue.component('TagLabel', TagLabel);
Vue.component('TagContent', TagContent);
Vue.component('TagsList', TagsList);

So you end up with several .js files and include them indivudually in the related blade templates that need each of them.

In your case as you only want to extract the Stripe libraries, mix.extract(...) also allows to specify which libraries to extract, the documentation is very detailed but in your webpack.mix.js file you would add something like this:

// Should match the NPM package name
// here I am assuming the Stripe NPM package is called 'stripe'
mix.extract(['stripe']);

Even If you extract only one library like that you'll need to include the generated manifest.js file on every blade template (probably on your master layout template), but you'll only need to include the generated vendor.js on the templates that need one of the extracted packages.

axtg's avatar
axtg
OP
Best Answer
Level 5

I appreciate your line of thought Rodrigo, thanks. Originally I was looking to do something like below:

.js(
  [
    'resources/js/components/subscription/*',
    'resources/js/components/meetings/*',
    'resources/js/components/attendees/*',
  ], 'public/js/auth.js',
)

If the user is authenticated: include the auth.js file. But this didn't work.

So I started looking at dynamic imports.

I replaced

Vue.component('create-subscription', require('./components/CreateSubscription.vue').default);

With

Vue.component('create-subscription', () => import('./components/CreateSubscription.vue'));

And then...

  1. Added @babel/preset-env and @babel/plugin-syntax-dynamic-import via npm
  2. Removed extract() from webpack.mix.js
  3. Set output folder for chunks in webpack config

That now seems to work. I include the remote Stripe libraries (there is no npm, just cdn for realtime risk analysis) when at the checkout page.

Happy Thanksgiving.

1 like
rodrigo.pedra's avatar

Nice approach, great you found a solution.

I generally don't reach for dynamic imports as most of the projects I work on are internal tools at business with few modules, so loading everything is not a pain and support for old browsers is required. But I'll definitely look for using them more.

Didn't know output folder for chunks was configurable (at least from Laravel mix), I guess this was one of the reasons I skipped using dynamic imports as it seemed to clutter the public folder a lot.

Thanks for the insights and Happy Thanksgiving.

Please or to participate in this conversation.