ohffs's avatar
Level 50

Splitting vue/js components

I've got an app where the javascript is getting a bit out of hand (~3mb so far and there's a lot more of the app to go). Most of the JS is actually for the admin back-end so it seems a shame to be hitting regular users with a huge bundle when they'll never need to use it.

Anyway - after a bit of googling around I've found roughly 8,000 ways of doing this - none of which seemed terribly helpful ;-) What I'm after is more-or-less a main app.js file with vue + some components/mixins which are used almost everywhere, then on individual pages be able to add in the bigger components that page uses. So in blade terms, something like :

.... regular blade stuff

@push('scripts')

@include('/js/app.js')
@include('/js/componentX.js')
@include('/js/componentY.js');

@endpush

But I'm not sure how to do that or if it's really possible with vue/components :-( Another thought I had was to make something like a 'page bundle' that had all the js needed for that particular page - but that seems like a maintenance nightmare.

Anyone have any pointers? It'd be much appreciated :-)

0 likes
7 replies
martinbean's avatar
Level 80

@ohffs I’ve been looking at this myself. It seems the way to go is “code splitting” in Webpack. Your code basically gets wrapped in callbacks that are then invoked when they’re needed.

I’ve not gotten around to implementing this myself, but given more time it would be what I’d implement :)

1 like
ohffs's avatar
Level 50

@martinbean ah! spiffy! Ta for that :-) I'll have a dig through that tomorrow when I'm not full of beer (a craft beer shop has opened up just round the corner from me - so I'm busy 'supporting local businesses'. :: hic :: ;-) It feels like splitting all this should be quite common - but googling about feels like 'why do you want to do that, you weirdo?' ;-)

Have a good weekend - thanks again :-)

ohffs's avatar
Level 50

@Cronix oh! thank you! that's exactly what I was failing to find by myself :-D

ohffs's avatar
Level 50

Just in case anyone else finds this - I've gone down the route of using Vue's Async components : https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components - which combined with the info from the pages above seems to be doing a whole lot of magic I am gladly ignoring for the moment - but it seems to work with a minimum of changes to the code.

A quick how-to:

Install the babel plugin to handle the not-yet-a-standard import() function :

npm install babel-plugin-syntax-dynamic-import --save-dev

Create a .babelrc file in the root of your project :

{
    "presets": [
        "babel-preset-env"
    ],
    "plugins": [
        "babel-plugin-syntax-dynamic-import"
    ]
}

In your app.js file, where you (or at least I was) doing :

Vue.component("order-form", require("./components/OrderForm.vue"));

Replace those require statements with :

Vue.component("order-form", () => import("./components/OrderForm.vue"));

Now when you run npm run dev (or whatever) webpack will magically split your components into different files and load them via ajax when needed in a template. Webpack will give them fairly unhelpful names - so if you care or want more control you can do :

Vue.component("order-form", () => import("./components/OrderForm.vue" /* webpackChunkName: "js/order-form" */));

Which will spit out the needed js into public/js/order-form.js (the default would be something like public/13.js.

Anyway - it's let me 1/2 the size of my app.js bundle - so that's a win for me. Thanks again to @Cronix and @martinbean for the pointers :-)

martinbean's avatar

@ohffs Glad you got it sorted. Makes me want to properly send some time aside and split a couple of my applications’ components :D

ohffs's avatar
Level 50

@martinbean it's surprisingly easy if you're happy to embrace the magic webpack is doing :-) Once I realised the async components were a thing - it was only about 15 minutes to change over :-) It is a teeny bit slower to load a page with components as it's fetching them via ajax - so sometimes there's a bit of a jank when it appears - but tbh that's the least of my worries ;-)

I do have the nagging doubt that something, somewhere is going terribly wrong of course - but then that's life as a software dev ;-)

Please or to participate in this conversation.